Bevezetés az XPath-ba Java-val

1. Áttekintés

Ebben a cikkben áttekintjük az XPath alapjai a standard Java JDK támogatásával.

Egy egyszerű XML dokumentumot fogunk használni, feldolgozzuk és megnézzük, hogyan kell áttekinteni a dokumentumot, hogy kibontsuk belőle a szükséges információkat.

Az XPath a W3C által ajánlott szabványos szintaxis, ez egy kifejezéskészlet az XML dokumentumok közötti navigáláshoz. Itt megtalálhatja a teljes XPath referenciát.

2. Egyszerű XPath elemző

importálja a javax.xml.namespace.NamespaceContext; importálja a javax.xml.parsers.DocumentBuilder; javax.xml.parsers.DocumentBuilderFactory importálása; importálja a javax.xml.parsers.ParserConfigurationException; importálja a javax.xml.xpath.XPath; importálja a javax.xml.xpath.XPathConstants alkalmazást; import javax.xml.xpath.XPathExpressionException; importálja a javax.xml.xpath.XPathFactory; import org.w3c.dom.Document; public class DefaultParser {privát fájl fájl; public DefaultParser (Fájl fájl) {this.file = fájl; }} 

Most nézzük meg közelebbről azokat az elemeket, amelyeket a DefaultParser:

FileInputStream fileIS = új FileInputStream (this.getFile ()); DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance (); DocumentBuilder builder = builderFactory.newDocumentBuilder (); XmlDocument = builder.parse (fileIS) dokumentum; XPath xPath = XPathFactory.newInstance (). NewXPath (); String kifejezés = "/ oktatóanyagok / oktatóanyag"; nodeList = (NodeList) xPath.compile (kifejezés) .értékelje (xmlDocument, XPathConstants.NODESET);

Bontjuk le ezt:

DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance ();

Ezt az objektumot használjuk egy DOM objektumfa előállítására az xml dokumentumunkból:

DocumentBuilder builder = builderFactory.newDocumentBuilder ();

Ennek az osztálynak a példányával elemezhetjük az XML dokumentumokat számos különböző bemeneti forrásból, például InputStream, File, URL és SAX:

XmlDocument = builder.parse (fileIS) dokumentum;

A Dokumentum (org.w3c.dom.Document) a teljes XML dokumentumot képviseli, a dokumentumfa gyökere, biztosítja az első hozzáférést az adatokhoz:

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

Az XPath objektumból hozzáférünk a kifejezésekhez és végrehajtjuk őket a dokumentumunkon keresztül, hogy kivonhassuk belőle a szükségeseket:

xPath.compile (kifejezés) .evaluate (xmlDocument, XPathConstants.NODESET);

Összeállíthatunk egy karaktersorozatként átadott XPath kifejezést, és meghatározhatjuk, hogy milyen adatokra számítunk az ilyen a fogadására NODESET, CSOMÓPONT vagy Húr például.

3. Kezdjük

Most, hogy megvizsgáltuk az általunk használt alapkomponenseket, tesztelési céllal kezdhetünk néhány kódot néhány egyszerű XML használatával:

   Guava Bevezetés a Guava-ba 2016.04.04. GuavaAuthor XML Bevezetés az XPath-ba 2016.05.04. XMLAuthor 

3.1. Töltse le az elemek alaplistáját

Az első módszer egy XPath-kifejezés egyszerű használata a csomópontok listájának lekérésére az XML-ből:

FileInputStream fileIS = új FileInputStream (this.getFile ()); DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance (); DocumentBuilder builder = builderFactory.newDocumentBuilder (); XmlDocument = builder.parse (fileIS) dokumentum; XPath xPath = XPathFactory.newInstance (). NewXPath (); String kifejezés = "/ oktatóanyagok / oktatóanyag"; nodeList = (NodeList) xPath.compile (kifejezés) .értékelje (xmlDocument, XPathConstants.NODESET); 

A gyökércsomópontban található oktató listát a fenti kifejezés használatával vagy a „// Oktatóanyag”De ez az összes megszerzi csomópontok a dokumentumban az aktuális csomópontból, függetlenül attól, hogy hol helyezkednek el a dokumentumban, ez azt jelenti, hogy a fa bármely szintjén az aktuális csomóponttól kezdődik.

A NodeList megadásával tér vissza NODESET a fordítási utasításhoz, mint visszatérési típus, a csomópontok rendezett gyűjteménye, amelyhez egy index, mint paraméter átadásával lehet hozzáférni.

3.2. Egy adott csomópont lekérése az azonosítója alapján

Bármely adott azonosító alapján megkereshetünk egy elemet, csak szűréssel:

DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance (); DocumentBuilder builder = builderFactory.newDocumentBuilder (); XmlDocument = builder.parse (this.getFile ()) dokumentum; XPath xPath = XPathFactory.newInstance (). NewXPath (); Karaktersorozat kifejezés = "/ oktatóanyagok / oktatóanyag [@ tutId =" + "" "+ id +" "" + "]"; csomópont = (Csomópont) xPath.compile (kifejezés) .értékelje (xmlDocument, XPathConstants.NODE); 

Az ilyen kifejezések használatával a megfelelő szintaxis használatával szűrhetünk bármilyen elemet, amelyet meg kell keresnünk. Ezeket a kifejezéseket predikátumoknak nevezzük, és egyszerű módon megkereshetik az adatokat a dokumentum felett, például:

/ Oktatóanyagok / oktatóanyagok [1]

/ Oktatóanyagok / oktatóanyagok [első ()]

/ Oktatóanyagok / oktatóanyagok [pozíció () <4]

A predikátumok teljes referenciáját itt találja

3.3. Csomópontok lekérése meghatározott címke név alapján

Most tovább megyünk a tengelyek bevezetésével, és megnézhetjük, hogyan működik ez, ha XPath kifejezésben használjuk:

XmlDocument = builder.parse (this.getFile ()) dokumentum; this.clean (xmlDocument); XPath xPath = XPathFactory.newInstance (). NewXPath (); Karakterlánc-kifejezés = "// oktatóanyag [leszármazott :: cím [szöveg () =" + "'" + név + "'" + "]]"; nodeList = (NodeList) xPath.compile (kifejezés) .értékelje (xmlDocument, XPathConstants.NODESET); 

A fent használt kifejezéssel mindenkit keresünk elem, akinek leszármazottja van a „name” változó paraméterként átadott szöveggel.

A cikkhez mellékelt xml mintát követve megkereshetnénk a „Guava” vagy „XML” szöveget tartalmaz, és lekérjük az egészet elem minden adatával.

A tengelyek nagyon rugalmas módot kínálnak az XML-dokumentumok navigálásához, és a teljes dokumentációt megtalálhatja a hivatalos oldalon.

3.4. Adatok kezelése kifejezésekben

Az XPath lehetővé teszi számunkra az adatok manipulálását a kifejezésekben is, ha szükséges.

XPath xPath = XPathFactory.newInstance (). NewXPath (); Karakterlánc-kifejezés = "// Oktatóanyag [szám (fordítás (dátum, '/', '')))>" + dátum + "]"; nodeList = (NodeList) xPath.compile (kifejezés) .értékelje (xmlDocument, XPathConstants.NODESET); 

Ebben a kifejezésben egy egyszerű karakterláncot adunk át dátumként, amely úgy néz ki, hogy „ééééééé”, de az XML ezeket az adatokat a „éééé / hh / nn“, Így az eredmény elérése érdekében manipuláljuk a karakterláncot, hogy a dokumentumunk által használt helyes adatformátumra konvertáljuk, és az XPath által biztosított egyik funkció használatával hajtjuk végre.

3.5. Elemek lekérése a névtérrel meghatározott dokumentumból

Ha az xml dokumentumunknak van egy névtere, amelyet az itt használt example_namespace.xml fájlban definiáltak, akkor a szükséges adatok lekérésére vonatkozó szabályok megváltoznak, mivel az xml a következő módon indul:

Most, amikor a „// Tutorial ”, nem fogunk eredményt elérni. Ez az XPath kifejezés mindent vissza fog adni elemek, amelyek nem szerepelnek semmilyen névtérben, és az új example_namespace.xml fájlban mind az elemeket a névtér határozza meg / full_archive.

Lássuk, hogyan kell kezelni a névtereket.

Először be kell állítanunk a névtér kontextust, hogy az XPath tudni tudja, hol keressük az adatainkat:

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

A fenti módszerben meghatározzukbdn”Névterünk neve”/ full_archive", És mostantól hozzá kell tennünk"bdn”Az elemek megkeresésére használt XPath kifejezésekhez:

String kifejezés = "/ bdn: oktatóanyagok / bdn: oktatóanyagok"; nodeList = (NodeList) xPath.compile (kifejezés) .értékelje (xmlDocument, XPathConstants.NODESET); 

A fenti kifejezés segítségével képesek vagyunk az összes lekérésére elemek a „bdn”Névtér.

3.6. Az üres szövegcsomópontokkal kapcsolatos problémák elkerülése

Amint észrevehette, a cikk 3.3 szakaszában található kódban egy új függvényt hívnak meg közvetlenül azután, hogy XML-jünket elemezzük egy Document objektumnak, ez a .clean (xmlDocument);

Néha, amikor elemeket, gyermekcsomópontokat stb. Folytatunk, ha a dokumentumunkban üres szövegcsomópontok találhatók, akkor váratlan viselkedést találhatunk a kívánt eredményekben.

Hívtuk csomópont .getFirstChild () amikor az egészet iteráljuk elemek keresik a információkat, de a keresett helyett csak a „#Text” van üres csomópontként.

A probléma kijavításához navigálhatunk a dokumentumunkban, és eltávolíthatjuk ezeket az üres csomópontokat, így:

NodeList childs = node.getChildNodes (); for (int n = childs.getLength () - 1; n> = 0; n--) {Csomópont gyermek = childs.item (n); rövid nodeType = gyermek.getNodeType (); if (nodeType == Node.ELEMENT_NODE) ​​{tiszta (gyermek); } else if (nodeType == Node.TEXT_NODE) ​​{String trimmedNodeVal = gyermek.getNodeValue (). trim (); if (trimmedNodeVal.length () == 0) {node.removeChild (gyermek); } else {child.setNodeValue (trimmedNodeVal); }} else if (nodeType == Node.COMMENT_NODE) ​​{node.removeChild (gyermek); }}

Ezzel ellenőrizhetjük az összes megtalált csomópontot, és eltávolíthatjuk azokat, amelyekre nincs szükségünk.

4. Konklúziók

Itt most bemutattuk az alapértelmezett XPath támogatást, de sok népszerű könyvtár létezik, mint JDOM, Saxon, XQuery, JAXP, Jaxen vagy akár Jackson. Vannak könyvtárak speciális HTML elemzéshez is, például a JSoup.

Ez nem korlátozódik a java-ra, az XPLT kifejezéseket az XSLT nyelv használhatja az XML dokumentumok navigálásához.

Mint láthatja, sokféle lehetőség kínálkozik az ilyen típusú fájlok kezelésére.

Alapértelmezés szerint nagyszerű támogatást nyújt az XML / HTML dokumentumok elemzése, olvasása és feldolgozása. A teljes működő mintát itt találja.