Úvod do XPath s Javou

1. Prehľad

V tomto článku si povieme niečo viac základy XPath s podporou v štandardnom Java JDK.

Budeme používať jednoduchý dokument XML, spracujeme ho a uvidíme, ako prejsť dokumentom, aby sme z neho vyťažili potrebné informácie.

XPath je štandardná syntax odporúčaná W3C, je to sada výrazov na navigáciu v dokumentoch XML. Celý odkaz na XPath nájdete tu.

2. Jednoduchý analyzátor XPath

import javax.xml.namespace.NamespaceContext; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.xpath.XPath; import javax.xml.xpath.XPathConstants; import javax.xml.xpath.XPathExpressionException; import javax.xml.xpath.XPathFactory; import org.w3c.dom.Document; verejná trieda DefaultParser {súkromný súbor; public DefaultParser (súbor súboru) {this.file = súbor; }} 

Teraz sa pozrime bližšie na prvky, ktoré nájdete v priečinku DefaultParser:

FileInputStream fileIS = nový FileInputStream (this.getFile ()); DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance (); DocumentBuilder builder = builderFactory.newDocumentBuilder (); Dokument xmlDocument = builder.parse (fileIS); XPath xPath = XPathFactory.newInstance (). NewXPath (); Reťazcový výraz = "/ Návody / Výukový program"; nodeList = (NodeList) xPath.compile (výraz) .evaluate (xmlDocument, XPathConstants.NODESET);

Poďme to rozdeliť:

DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance ();

Tento objekt použijeme na vytvorenie stromu objektov DOM z nášho dokumentu XML:

DocumentBuilder builder = builderFactory.newDocumentBuilder ();

Vďaka inštancii tejto triedy môžeme analyzovať dokumenty XML z mnohých rôznych vstupných zdrojov, napríklad InputStream, Súbor, URL a SAX:

Dokument xmlDocument = builder.parse (fileIS);

A Dokument (org.w3c.dom.Doklad) predstavuje celý dokument XML, je koreňom stromu dokumentov, poskytuje náš prvý prístup k údajom:

XPath xPath = XPathFactory.newInstance (). NewXPath ();

Z objektu XPath pristúpime k výrazom a vykonáme ich v našom dokumente, aby sme z neho extrahovali to, čo potrebujeme:

xPath.compile (výraz) .evaluate (xmlDocument, XPathConstants.NODESET);

Môžeme zostaviť výraz XPath odovzdaný ako reťazec a definovať, aký druh údajov očakávame, že dostaneme taký NODESET, NODE alebo String napríklad.

3. Začnime

Teraz, keď sme sa pozreli na základné komponenty, ktoré budeme používať, začnime s kódom pomocou jednoduchého XML na účely testovania:

   Guava Introduction to Guava 04/04/2016 GuavaAuthor XML Úvod do XPath 04/05/2016 XMLAuthor 

3.1. Načítajte základný zoznam prvkov

Prvou metódou je jednoduché použitie výrazu XPath na získanie zoznamu uzlov z XML:

FileInputStream fileIS = nový FileInputStream (this.getFile ()); DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance (); DocumentBuilder builder = builderFactory.newDocumentBuilder (); Dokument xmlDocument = builder.parse (fileIS); XPath xPath = XPathFactory.newInstance (). NewXPath (); Reťazcový výraz = "/ Návody / Výukový program"; nodeList = (NodeList) xPath.compile (výraz) .evaluate (xmlDocument, XPathConstants.NODESET); 

Zoznam výučby obsiahnutý v koreňovom uzle môžeme načítať pomocou vyššie uvedeného výrazu alebo pomocou výrazu „// Výukový program„Ale tento načíta všetky uzly v dokumente z aktuálneho uzla bez ohľadu na to, kde sa v dokumente nachádzajú, to znamená na akejkoľvek úrovni stromu počnúc od aktuálneho uzla.

The NodeList vráti sa zadaním NODESET do inštrukcie kompilácie ako návratový typ, je usporiadaná kolekcia uzlov, ku ktorým je možné získať prístup cez index ako parameter.

3.2. Načítanie konkrétneho uzla podľa jeho ID

Element môžeme hľadať na základe ľubovoľného daného id iba filtrovaním:

DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance (); DocumentBuilder builder = builderFactory.newDocumentBuilder (); Dokument xmlDocument = builder.parse (this.getFile ()); XPath xPath = XPathFactory.newInstance (). NewXPath (); Reťazcový výraz = "/ Návody / Výukový program [@ tutId =" + "'" + id + "'" + "]"; node = (Node) xPath.compile (výraz) .evaluate (xmlDocument, XPathConstants.NODE); 

Použitím tohto druhu výrazov môžeme filtrovať ľubovoľný prvok, ktorý musíme hľadať, a to iba pomocou správnej syntaxe. Tieto druhy výrazov sa nazývajú predikáty a sú ľahkým spôsobom, ako vyhľadať konkrétne údaje v dokumente, napríklad:

/ Výukové programy / Výukový program [1]

/ Výukové programy / Výukový program [prvý ()]

/ Výukové programy / Výukový program [pozícia () <4]

Kompletný odkaz na predikáty nájdete tu

3.3. Načítanie uzlov pod konkrétnym názvom značky

Teraz ideme ďalej zavedením osí, pozrime sa, ako to funguje, pomocou výrazu XPath:

Dokument xmlDocument = builder.parse (this.getFile ()); this.clean (xmlDocument); XPath xPath = XPathFactory.newInstance (). NewXPath (); Reťazcový výraz = "// Výukový program [potomok :: názov [text () =" + "'" + meno + "" "+"]] "; nodeList = (NodeList) xPath.compile (výraz) .evaluate (xmlDocument, XPathConstants.NODESET); 

S výrazom použitým vyššie hľadáme všetky živel, ktorý má potomka s textom odovzdaným ako parameter v premennej „name“.

Podľa vzoru xml uvedeného v tomto článku by sme mohli hľadať a obsahujúci text „Guava“ alebo „XML“ a stiahneme celý prvok so všetkými jeho údajmi.

Osi poskytujú veľmi flexibilný spôsob navigácie v dokumente XML a úplnú dokumentáciu nájdete na oficiálnych stránkach.

3.4. Manipulácia s dátami vo výrazoch

XPath nám umožňuje v prípade potreby manipulovať aj s dátami vo výrazoch.

XPath xPath = XPathFactory.newInstance (). NewXPath (); Reťazcový výraz = "// Výukový program [číslo (preložiť (dátum, '/', ''))>" + dátum + "]"; nodeList = (NodeList) xPath.compile (výraz) .evaluate (xmlDocument, XPathConstants.NODESET); 

V tomto výraze odovzdávame našej metóde jednoduchý reťazec ako dátum, ktorý vyzerá ako „ddmmyyyy“, ale XML ukladá tieto údaje vo formáte „dd / mm / rrrr„, Aby sme porovnali výsledok, manipulujeme s reťazcom, aby sme ho konvertovali do správneho dátového formátu použitého v našom dokumente, a robíme to pomocou jednej z funkcií poskytovaných XPath

3.5. Načítanie prvkov z dokumentu s definovaným priestorom mien

Ak má náš dokument xml priestor názvov definovaný tak, ako je to v tu použitom príklade_namespace.xml, pravidlá načítania potrebných údajov sa zmenia, pretože náš súbor XML začína takto:

Keď teraz použijeme výraz podobný „// Tutorial ”, nedosiahneme žiadny výsledok. Tento výraz XPath vráti všetko prvky, ktoré sa nenachádzajú v žiadnom mennom priestore, a v našom novom example_namespace.xml všetky prvky sú definované v priestore mien / full_archive.

Pozrime sa, ako zaobchádzať s mennými priestormi.

Najskôr musíme nastaviť kontext menného priestoru, aby XPath mohol vedieť, kde hľadáme naše údaje:

xPath.setNamespaceContext (new NamespaceContext () {@Override public Iterator getPrefixes (String arg0) {return null;} @Override public String getPrefix (String arg0) {return null;} @Override public String getNamespaceURI (String arg0) {if (" bdn ".equals (arg0)) {return" / full_archive ";} return null;}}); 

Vo vyššie uvedenej metóde definujeme „bdn„Ako názov pre náš priestor mien“/ full_archive„A odteraz musíme dodať“bdn”K výrazom XPath použitým na vyhľadanie prvkov:

Reťazcový výraz = "/ bdn: Výukové programy / bdn: Výukový program"; nodeList = (NodeList) xPath.compile (výraz) .evaluate (xmlDocument, XPathConstants.NODESET); 

Pomocou vyššie uvedeného výrazu môžeme získať všetky prvky pod „bdn”Menný priestor.

3.6. Predchádzanie problémom s prázdnymi textovými uzlami

Ako ste si mohli všimnúť, v kóde v časti 3.3 tohto článku sa volá nová funkcia hneď po analýze nášho XML na objekt Document, this .clean (xmlDocument);

Niekedy, keď iterujeme prvkami, detskými uzlami a tak ďalej, ak má náš dokument prázdne textové uzly, môžeme vo výsledkoch, ktoré chceme získať, nájsť neočakávané správanie.

Volali sme uzol .getFirstChild () keď iterujeme nanovo prvky hľadajúce informácie, ale namiesto toho, čo hľadáme, máme ako prázdny uzol iba „#Text“.

Na vyriešenie problému môžeme prechádzať naším dokumentom a odstrániť tieto prázdne uzly, napríklad takto:

NodeList childs = node.getChildNodes (); for (int n = childs.getLength () - 1; n> = 0; n--) {Uzol dieťa = childs.item (n); short nodeType = child.getNodeType (); if (nodeType == Node.ELEMENT_NODE) ​​{čistý (dieťa); } else if (nodeType == Node.TEXT_NODE) ​​{Reťazec trimmedNodeVal = child.getNodeValue (). trim (); if (trimmedNodeVal.length () == 0) {node.removeChild (child); } else {child.setNodeValue (trimmedNodeVal); }} else if (nodeType == Node.COMMENT_NODE) ​​{node.removeChild (child); }}

Týmto spôsobom môžeme skontrolovať každý typ uzla, ktorý nájdeme, a odstrániť tie, ktoré nepotrebujeme.

4. Závery

Tu sme práve predstavili predvolenú podporu poskytovanú XPath, ale v súčasnosti existuje veľa populárnych knižníc ako JDOM, Saxon, XQuery, JAXP, Jaxen alebo dokonca Jackson. K dispozícii sú knižnice pre konkrétnu analýzu HTML, podobne ako JSoup.

Nie je to obmedzené na javu, výrazy XPath môžu byť použité jazykom XSLT na navigáciu v dokumentoch XML.

Ako vidíte, existuje veľa možností, ako s týmto typom súborov zaobchádzať.

Štandardne existuje veľká štandardná podpora pre analýzu, čítanie a spracovanie dokumentov XML / HTML. Celú pracovnú vzorku nájdete tu.


$config[zx-auto] not found$config[zx-overlay] not found