XPath og XQuery MBIB4140 Høst 2017 Thomas Sødring thomas.sodring@hioa.no P48-R407
Kilder Blanding av følgende World Wide Web Consortium. (1999a, 16. November). XML Path Language (XPath): Version 1.0. Hentet fra http://www.w3.org/TR/xpath/ World Wide Web Consortium. (2015, 7. September). XQuery 1.0: An XML Query Language
Læringsressurser Interne Eksterne Saxon http://saxon.sourceforge.net/ http://edu.hioa.no/mbib4140/current/ressurser/xml/ Eksterne Saxon http://saxon.sourceforge.net/ Saxon-HE Kan brukes for både XQuery og XSLT XPath tester http://www.xpathtester.com/xpath
I dag skal vi lære XPath syntaks, hva det er og hvordan det brukes XQuery Søke gjennom en XML-fil med XPath syntaks Fokus på FLOWR Saxon som verktøy for utføre XQuery spørringer
XML-stacken XPath XQuery XML XSLT XSD
Data / Struktur / Presentasjon Boken on xml Hans Hansen Introduksjon Dette er en bok om xml. XML Elementer og Attributter ....... Fysisk bok Data eBok Presentasjon En bok består av tittel,forfatter, kapitler, og paragrafer Lydbok Struktur og validering
XPath XPath er en syntaks som brukes til å navigere gjennom og filtrere et XML-tre Brukes i bla. XQuery XSLT
XML-filen vår <?xml version="1.0" encoding="UTF-8"?> <books> <book> <title>XKCD Volume 0</title> <authors> <author> <firstname>Randall</firstname> <lastname>Monroe</lastname> </author> </authors> <year>2003</year> <publisher>Breadpig</publisher> <isbn10>0615314465</isbn10> <isbn13>978-0615314464</isbn13> <price currency="NOK">325</price> </book> </books>
Noder og data I en XML fil så må vi skille mellom noder og innhold <?xml version="1.0" encoding="UTF-8"?> <books> <book> <title>XKCD Volume 0</title> <authors> <author> <firstname>Randall</firstname> <lastname>Monroe</lastname> </author> </authors> <year>2003</year> <publisher>Breadpig</publisher> <isbn10>0615314465</isbn10> <isbn13>978-0615314464</isbn13> <price currency="NOK">325</price> </book> <title>Web Services Essentials</title> <firstname>Ethan</firstname> <lastname>Cerami</lastname> <publisher>OReilly</publisher> <isbn>978-0-596-00224-41</isbn> <price currency="NOK">499</price> </books> I en XML fil så må vi skille mellom noder og innhold Metadata Data Struktur defineres av nodene Data er innhold i en node
Akser . Nåværende node .. Forleder node @ attributt <?xml version="1.0" encoding="UTF-8"?> <books> <book> <title>XKCD Volume 0</title> <authors> <author> <firstname>Randall</firstname> <lastname>Monroe</lastname> </author> </authors> <year>2003</year> <publisher>Breadpig</publisher> <isbn10>0615314465</isbn10> <isbn13>978-0615314464</isbn13> <price currency="NOK">325</price> </book> <title>Web Services Essentials</title> <firstname>Ethan</firstname> <lastname>Cerami</lastname> <publisher>OReilly</publisher> <isbn>978-0-596-00224-41</isbn> <price currency="NOK">499</price> </books> . Nåværende node .. Forleder node @ attributt <price currency="NOK">499</price>
Sti syntaks Bruker en sti syntaks for å navigere noder Vi bruker bare navnet til nodene Feks /books Hele dokumentet Et XPath uttrykk evalueres til å angi utvalgte deler av et XML-dokument /books/book/authors Alle authors som er et barn av book, som er et barn av books /books/book/price Alle price som er et barn av book, som er et barn av books
/books/book/authors <?xml version="1.0" encoding="UTF-8"?> <title>XKCD Volume 0</title> <authors> <author> <firstname>Randall</firstname> <lastname>Monroe</lastname> </author> </authors> <year>2003</year> <publisher>Breadpig</publisher> <isbn10>0615314465</isbn10> <isbn13>978-0615314464</isbn13> <price currency="NOK">325</price> </book> <title>Web Services Essentials</title> <firstname>Ethan</firstname> <lastname>Cerami</lastname> <publisher>OReilly</publisher> <isbn>978-0-596-00224-41</isbn> <price currency="NOK">499</price> </books>
/books/book/price <?xml version="1.0" encoding="UTF-8"?> <title>XKCD Volume 0</title> <authors> <author> <firstname>Randall</firstname> <lastname>Monroe</lastname> </author> </authors> <year>2003</year> <publisher>Breadpig</publisher> <isbn10>0615314465</isbn10> <isbn13>978-0615314464</isbn13> <price currency="NOK">325</price> </book> <title>Web Services Essentials</title> <firstname>Ethan</firstname> <lastname>Cerami</lastname> <publisher>OReilly</publisher> <isbn>978-0-596-00224-41</isbn> <price currency="NOK">499</price> </books>
Sti syntaks XML/XSD Du bør egentlig være litt mer opptatt av XSD beskrivelsen av XML-dokumentet framfor XML- dokumentet XML-dokumentet kan være 100 000+ linjer lang XSD-filen er langt ryddigere og enklere å forholde seg til
XSD-beskrivelse ?xml version="1.0"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" attributeFormDefault="unqualified" elementFormDefault="qualified"> <xs:element name="books"> <xs:complexType> <xs:sequence> <xs:element name="book" maxOccurs="unbounded" minOccurs="0"> <xs:element type="xs:string" name="title"/> <xs:element name="authors"> <xs:element name="author"> <xs:element type="xs:string" name="firstname"/> <xs:element type="xs:string" name="lastname"/> </xs:sequence> </xs:complexType> </xs:element> <xs:element type="xs:short" name="year"/> <xs:element type="xs:string" name="publisher"/> <xs:element type="xs:string" name="isbn10" minOccurs="0"/> <xs:element type="xs:string" name="isbn13" minOccurs="0"/> <xs:element type="xs:string" name="isbn" minOccurs="0"/> <xs:element name="price"> <xs:simpleContent> <xs:extension base="xs:short"> <xs:attribute type="xs:string" name="currency" use="optional"/> </xs:extension> </xs:simpleContent> </xs:schema>
Viktigheten av XSD <?xml version="1.0" encoding="UTF-8"?> <books> <book> <title>XKCD Volume 0</title> <authors> <author> <firstname>Randall</firstname> <lastname>Monroe</lastname> </author> </authors> <year>2003</year> <publisher>Breadpig</publisher> <isbn10>0615314465</isbn10> <isbn13>978-0615314464</isbn13> <price currency="NOK">325</price> </book> <bok> <title>Web Services Essentials</title> <firstname>Ethan</firstname> <lastname>Cerami</lastname> <publisher>OReilly</publisher> <isbn>978-0-596-00224-41</isbn> <price currency="NOK">499</price> </bok> </books> Hvis du ikke kan validere XML- dokumentet ditt med en XSD, så kan du heller ikke være sikker at XPath syntaksen fanger alt Et element som heter <bok> blir ikke fanget opp i /books/book/authors
/ og // // er en slags joker (wildcard) som kan angi en vilkårlig node <?xml version="1.0" encoding="UTF-8"?> <books> <book> <title>XKCD Volume 0</title> <authors> <author> <firstname>Randall</firstname> <lastname>Monroe</lastname> </author> </authors> <year>2003</year> <publisher>Breadpig</publisher> <isbn10>0615314465</isbn10> <isbn13>978-0615314464</isbn13> <price currency="NOK">325</price> </book> <bok> <title>Web Services Essentials</title> <firstname>Ethan</firstname> <lastname>Cerami</lastname> <publisher>OReilly</publisher> <isbn>978-0-596-00224-41</isbn> <price currency="NOK">499</price> </bok> </books> // er en slags joker (wildcard) som kan angi en vilkårlig node /books//authors Løser 'problemet' der noder ikke er riktig definert som feks <bok> blir ikke fanget opp i /books/book/authors
/ og // / brukes til å angi en node // brukes som joker tegn //authors <?xml version="1.0" encoding="UTF-8"?> <books> <book> <title>XKCD Volume 0</title> <authors> <author> <firstname>Randall</firstname> <lastname>Monroe</lastname> </author> </authors> <year>2003</year> <publisher>Breadpig</publisher> <isbn10>0615314465</isbn10> <isbn13>978-0615314464</isbn13> <price currency="NOK">325</price> </book> <audiobook> <title>Web Services Essentials</title> <firstname>Ethan</firstname> <lastname>Cerami</lastname> <publisher>OReilly</publisher> <isbn>988-1-793-01391-25</isbn> <price currency="NOK">299</price> </audiobook> </books> / brukes til å angi en node // brukes som joker tegn //authors Brukes der du har behov for litt mer fleksibilitet i filtreringen
(/books/book/authors)[1] <?xml version="1.0" encoding="UTF-8"?> <books> <book> <title>XKCD Volume 0</title> <authors> <author> <firstname>Randall</firstname> <lastname>Monroe</lastname> </author> </authors> <year>2003</year> <publisher>Breadpig</publisher> <isbn10>0615314465</isbn10> <isbn13>978-0615314464</isbn13> <price currency="NOK">325</price> </book> <title>Web Services Essentials</title> <firstname>Ethan</firstname> <lastname>Cerami</lastname> <publisher>OReilly</publisher> <isbn>978-0-596-00224-41</isbn> <price currency="NOK">499</price> </books>
(/books/book/authors)[2] <?xml version="1.0" encoding="UTF-8"?> <books> <book> <title>XKCD Volume 0</title> <authors> <author> <firstname>Randall</firstname> <lastname>Monroe</lastname> </author> </authors> <year>2003</year> <publisher>Breadpig</publisher> <isbn10>0615314465</isbn10> <isbn13>978-0615314464</isbn13> <price currency="NOK">325</price> </book> <title>Web Services Essentials</title> <firstname>Ethan</firstname> <lastname>Cerami</lastname> </authors> <year>2003</year> <publisher>OReilly</publisher> <isbn>978-0-596-00224-41</isbn> <price currency="NOK">499</price> </books>
XPath syntaks Vi kan videre filtrere på sti utrykket (/books/book/authors)[1] Bryter med foreldre / barn rekkefølge
XPath operatorer XPath har følgende operatorer /, //, [] +, -, *, div, og mod <, <=, >, >=, =, != and or og not | Når ser vi på noen av disse
/books/book/price[@currency='NOK'] <?xml version="1.0" encoding="UTF-8"?> <books> <book> <title>XKCD Volume 0</title> <authors> <author> <firstname>Randall</firstname> <lastname>Monroe</lastname> </author> </authors> <year>2003</year> <publisher>Breadpig</publisher> <isbn10>0615314465</isbn10> <isbn13>978-0615314464</isbn13> <price currency="NOK">325</price> </book> <title>Web Services Essentials</title> <firstname>Ethan</firstname> <lastname>Cerami</lastname> <publisher>OReilly</publisher> <isbn>978-0-596-00224-41</isbn> <price currency="NOK">499</price> </books> Her ser vi bruken av = operator Filtrering av attributter i XML element
/books/book [price > 325] <?xml version="1.0" encoding="UTF-8"?> <books> <book> <title>XKCD Volume 0</title> <authors> <author> <firstname>Randall</firstname> <lastname>Monroe</lastname> </author> </authors> <year>2003</year> <publisher>Breadpig</publisher> <isbn10>0615314465</isbn10> <isbn13>978-0615314464</isbn13> <price currency="NOK">325</price> </book> <title>Web Services Essentials</title> <firstname>Ethan</firstname> <lastname>Cerami</lastname> <publisher>OReilly</publisher> <isbn>978-0-596-00224-41</isbn> <price currency="NOK">499</price> </books> Her ser vi bruken av > operator Husk at price noden er et barn av book noden Vi kan filtrere på alle noder som er et barn av book noden
/books/book [price > 325 and authors/author/lastname = 'Cerami' ] <?xml version="1.0" encoding="UTF-8"?> <books> <book> <title>XKCD Volume 0</title> <authors> <author> <firstname>Randall</firstname> <lastname>Monroe</lastname> </author> </authors> <year>2003</year> <publisher>Breadpig</publisher> <isbn10>0615314465</isbn10> <isbn13>978-0615314464</isbn13> <price currency="NOK">325</price> </book> <title>Web Services Essentials</title> <firstname>Ethan</firstname> <lastname>Cerami</lastname> <publisher>OReilly</publisher> <isbn>978-0-596-00224-41</isbn> <price currency="NOK">499</price> </books> Her ser vi bruken av and operator > og = operator XML-sti som er en subset av hoved spørringen
/books/book [price > 325 and authors/author/lastname = 'Cerami' ] <?xml version="1.0" encoding="UTF-8"?> <books> <book> <title>XKCD Volume 0</title> <authors> <author> <firstname>Randall</firstname> <lastname>Monroe</lastname> </author> </authors> <year>2003</year> <publisher>Breadpig</publisher> <isbn10>0615314465</isbn10> <isbn13>978-0615314464</isbn13> <price currency="NOK">325</price> </book> <title>Web Services Essentials</title> <firstname>Ethan</firstname> <lastname>Cerami</lastname> <publisher>OReilly</publisher> <isbn>978-0-596-00224-41</isbn> <price currency="NOK">499</price> </books> Her ser vi bruken av and operator > og = operator XML-sti som er en subset av hoved spørringen
/books/book/price | /books/book/year <?xml version="1.0" encoding="UTF-8"?> <books> <book> <title>XKCD Volume 0</title> <authors> <author> <firstname>Randall</firstname> <lastname>Monroe</lastname> </author> </authors> <year>2003</year> <publisher>Breadpig</publisher> <isbn10>0615314465</isbn10> <isbn13>978-0615314464</isbn13> <price currency="NOK">325</price> </book> <title>Web Services Essentials</title> <firstname>Ethan</firstname> <lastname>Cerami</lastname> <publisher>OReilly</publisher> <isbn>978-0-596-00224-41</isbn> <price currency="NOK">499</price> </books> Her ser vi bruken av | operator Kombinere to forskjellige noder
XPath funksjoner Manipulere strenger string-length(), normalize-space(), substring(), concat(), contains(), substring-before(), substring-after() Manipulere numre sum(), round(), floor(), ceiling() Posisjon position(), last() Egenskaper til noder name(), local-name(), namespace-uri() Type konvertering string(), number(), boolean()
/books/book [starts-with(authors/author/lastname, 'Ce') ] <?xml version="1.0" encoding="UTF-8"?> <books> <book> <title>XKCD Volume 0</title> <authors> <author> <firstname>Randall</firstname> <lastname>Monroe</lastname> </author> </authors> <year>2003</year> <publisher>Breadpig</publisher> <isbn10>0615314465</isbn10> <isbn13>978-0615314464</isbn13> <price currency="NOK">325</price> </book> <title>Web Services Essentials</title> <firstname>Ethan</firstname> <lastname>Cerami</lastname> <publisher>OReilly</publisher> <isbn>978-0-596-00224-41</isbn> <price currency="NOK">499</price> </books> Her ser vi bruken av starts-with funksjon Angir noden vi vil søke i hva innholdet begynner med Tilsvarer like 'Ce%' i SQL
/books/book [contains(title, 'XKCD') ] <?xml version="1.0" encoding="UTF-8"?> <books> <book> <title>XKCD Volume 0</title> <authors> <author> <firstname>Randall</firstname> <lastname>Monroe</lastname> </author> </authors> <year>2003</year> <publisher>Breadpig</publisher> <isbn10>0615314465</isbn10> <isbn13>978-0615314464</isbn13> <price currency="NOK">325</price> </book> <title>Web Services Essentials</title> <firstname>Ethan</firstname> <lastname>Cerami</lastname> <publisher>OReilly</publisher> <isbn>978-0-596-00224-41</isbn> <price currency="NOK">499</price> </books> Her ser vi bruken av contains funksjon Angir noden vi vil søke i innholdet vi søker etter Tilsvarer like '%title%' i SQL
innholdet vi søker etter Tilsvarer like '%title%' i SQL /books/book [ contains(title, 'XKCD') or contains(title, 'Essentials') ] <?xml version="1.0" encoding="UTF-8"?> <books> <book> <title>XKCD Volume 0</title> <authors> <author> <firstname>Randall</firstname> <lastname>Monroe</lastname> </author> </authors> <year>2003</year> <publisher>Breadpig</publisher> <isbn10>0615314465</isbn10> <isbn13>978-0615314464</isbn13> <price currency="NOK">325</price> </book> <title>Web Services Essentials</title> <firstname>Ethan</firstname> <lastname>Cerami</lastname> <publisher>OReilly</publisher> <isbn>978-0-596-00224-41</isbn> <price currency="NOK">499</price> </books> Her ser vi bruken av contains funksjon Angir noden vi vil søke i innholdet vi søker etter Tilsvarer like '%title%' i SQL
Filtrer på lengde til streng Velg bøker med tittel lengde større enn 14 /books/book [ string-length(title) > 14] Velg bøker med tittel lengde lik 13 /books/book [ string-length(title) = 13]
XPath funksjoner - posisjon Velg annenhver bok /books/book [postion() mod 2 = 1] /books/book [postion() mod 2 = 0] Velg siste bok i XML-treet /books/book [last()]
XPath funksjoner - nummer Totalpris på alle bøker sum (/books/book/price) Antall bøker i XML-dokumentet count (/books/book) Snitt pris på alle bøker sum (/books/book/price) div count (/books/book/price) Hva med denne?
XPath XPath har utviklet seg fra versjon 1.0 1.0, 2.0, 3.0 og 3.1 avg (/books/book/price) i 2.0 XPath er et nyttig verktøy å kunne mestre hvis du jobber med store XML-dokumenter og du har et behov for å filtrere / navigere gjennom filen på På arkivsiden finnes det en liste med XPath syntaks som kan brukes til å validere arkivstruktur.xml IKA Trøndelag Brukes også med programeringspråk og XQuery og XSLT
XML-stacken XPath XQuery XML XSLT XSD
XQuery Det SQL er til en database, XQuery er til en XML- fil XQuery er et spørrespråk for XML Bruker XPath syntaks for å navigere XML- treet Du er avhengig av en XQuery prosessor for å kunne utføre spørringer Bruke både Saxon http://www.xpathtester.com/xquery
SQL Oppfrisking ... SELECT * FROM books SELECT title FROM books WHERE year > 2004 SELECT * FROM books WHERE year > 2004 ORDER BY title DESC
FLWOR FOR WHERE ORDER BY RETURN for $book in /books/book return $book for $book in /books/book where $book/year > 2001 return $book/title ORDER BY for $book in /books/book where $book/year > 2001 order by $book/year descending return $book/title RETURN for $book in /books/book where $book/year > 2001 return <book>{$book/title}{$book/price} </book>
FLWOR - return Under return kan du enten bare returnere en instans av det du har definert under for delen return $book return $book/title Eller så kan du ha litt mer kontroll <book> {$book/title}{$book/price} </book> Her markerer vi hver node av resultatet med <book></book> {} brukes til å angi hva du vil returnere
FLWOR - return Vi ønsker kanskje å lage et korrekt strukturert XML-dokument Men litt som med SQL så er returnert enhet data, ikke et XML-dokument for $books in /books return <books> { for $book in $books/book where $book/year > 2001 return <book> for $authors in $book/authors return <authors> <author> { $authors/author/firstname } </author> </authors> } { $book/price } { $book/title } </book> </books>
FLWOR - return return returnerer noe per gjennomgang av en for Hvis du har erfaring med programmering så må du ikke forveksle return med feks return brukt ved slutten av en funksjon kall for $book in /books/book return $book/title
FLWOR - return Vi ønsker kanskje å lage et korrekt strukturert XML-dokument Men litt som med SQL så er returnert enhet data, ikke et XML-dokument for $books in /books return <books> { for $book in $books/book where $book/year > 2001 return <book> for $authors in $book/authors return ( <authors> <author> { concat ( $authors/author/firstname , ' ', $authors/author/lastname ) } </author> </authors> ) } { $book/price } { $book/title } </book> </books>
FLWOR – where Som med SQL kan vi filtrere med boolske uttrykk Her bruker vi XPath syntaks for å hjelpe oss for $book in /books/book where $book/year > 2001 and contains($book/title, 'XKCD') return $book
FLWOR – XPath i return Kan også bruke XPath funksjoner som en del av return Her bruker vi XPath funksjon substring-after for å fjerne det første ordet for $book in /books/book where $book/year > 2001 and contains($book/title, 'XKCD') return substring-after($book/title, ' ')
FLWOR – XPath i return Kan også bruke XPath funksjoner som en del av return Her bruker vi XPath funksjon substring-before for å fjerne alt etter første ordet for $book in /books/book where $book/year > 2001 and contains($book/title, 'XKCD') return substring-before($book/title, ' ')
FLWOR – order by Som med SQL kan sortere returnert innhold Sortere etter flere kolonner, både stigende og synkende for $book in /books/book where $book/year > 2001 order by $book/year descending, $book/title ascending return $book/title
XPath versus XQuery XPath kan filtrere innhold i et XML-dokument men har begrenset støtte for SQL-type søk XQuery gir SQL-type søk og har også muligheten til å utføre joins Men det så vi ikke på her XQuery med FLOWR er mer fleksibel enn XPath De har hver sin rolle XPath for enkel filtrering og validering av innhold XQuery for mer avansert spørringer og mer i retning av programvare utvikling
XPath og XSLT Neste uke er det en introduksjon til XSLT XPath sti syntaks, funksjoner og operatrer brukes også i XSLT og beriker hva du kan gjøre med XSLT
Avslutningsvis Vi valgte ikke å se på L-delen av FLOWR L står for Let og lar deg angi variabler som er gjenbrukbar i XQuery'n din Ikke noe vanskelig men ville spist av tiden i dag Vi valgte å ikke se på joins da det også kompliserer bildet litt
Saxon Xquery kan også kjøres på kommandolinjen fra windows / Linux med et verktøy som heter Saxon Skal være installert på maskinen i P48-S558 Vi ser på det i klassen Alle eksemplene vi har testet i nettleser finner du https://edu.hioa.no/mbib4140/h17/ressurser/xq uery/
Saxon For å bruke saxon må du angi XQuery versjon og navnet på XML-filen xquery version "1.0"; for $book in doc("books.xml")/books/book where $book/year > 2001 return $book/title