XML-attribútum módosítása Java-ban

1. Bemutatkozás

Ha az XML-mel dolgozunk, az egyik általános tevékenység az attribútumokkal való munka. Ebben az oktatóanyagban azt vizsgáljuk meg, hogyan lehet módosítani az XML attribútumot a Java használatával.

2. Függőségek

A tesztjeink futtatásához hozzá kell adnunk a JUnit és xmlunit-assertj Maven projektünk függőségei:

 org.junit.jupiter junit-jupiter 5.5.0 teszt 
 org.xmlunit xmlunit-assertj 2.6.3 teszt 

3. A JAXP használata

Kezdjük egy XML dokumentummal:

  [e-mail védett] [e-mail védett] 

Feldolgozása érdekében megtesszük használja a Java API-t az XML-feldolgozáshoz (JAXP), amely az 1.4-es verzió óta csomagolva van a Java-val.

Módosítsuk a vevő attribútumot és értékét megváltoztatja hamis.

Először ki kell építenünk egy Dokumentum objektumot az XML fájlból, és ehhez a DocumentBuilderFactory:

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance (); factory.setFeature (XMLConstants.FEATURE_SECURE_PROCESSING, true); factory.setFeature ("// apache.org/xml/features/disallow-doctype-decl", igaz); Dokumentumbevitel = gyári .newDocumentBuilder () .parse (resourcePath);

Vegye figyelembe, hogy annak érdekében a külső entitás feldolgozásának letiltása (XXE) a DocumentBuilderFactory osztály, konfiguráljuk a XMLConstants.FEATURE_SECURE_PROCESSING és //apache.org/xml/features/disallow-doctype-decl jellemzők. Jó gyakorlat konfigurálni, amikor a nem megbízható XML fájlokat elemezzük.

Az inicializálás után bemenet objektum, meg kell keresnünk a csomópontot azzal az attribútummal, amelyet módosítani szeretnénk. Használjunk XPath kifejezést a kiválasztásához:

XPath xpath = XPathFactory .newInstance () .newXPath (); String expr = String.format ("// * [tartalmazza (@% s, '% s')]", attribútum, oldValue); NodeList csomópontok = (NodeList) xpath.evaluate (expr, input, XPathConstants.NODESET);

Ebben az esetben az XPath értékelni A method egy csomópont-listát ad vissza nekünk az egyező csomópontokkal.

Iteráljunk a lista felett az érték megváltoztatásához:

for (int i = 0; i <csomópontok.getLength (); i ++) {elem értéke = (elem) csomópontok.elem (i); value.setAttribute (attribútum, newValue); }

Vagy a helyett mert hurok, használhatunk egy IntStream:

IntStream .range (0, nodes.getLength ()) .mapToObj (i -> (Element) nodes.item (i)) .forEach (érték -> value.setAttribute (attribútum, newValue));

Most használjuk a Transzformátor objektum a módosítások alkalmazásához:

TransformerFactory gyár = TransformerFactory.newInstance (); factory.setFeature (XMLConstants.FEATURE_SECURE_PROCESSING, true); Transformer xformer = factory.newTransformer (); xformer.setOutputProperty (OutputKeys.INDENT, "igen"); Írókimenet = new StringWriter (); xformer.transform (új DOMSource (bemenet), új StreamResult (output));

Ha kinyomtatjuk a Kimenet objektum tartalmát, a kapott XML-t a vevő módosított attribútum:

  [e-mail védett] [e-mail védett] 

Használhatjuk a állítsa azt az XMLUnit metódusa, ha egységteszten kell ellenőriznünk:

assertThat (output.toString ()). hasXPath ("// * [tartalmazza (@customer, 'hamis')]");

4. A dom4j használata

A dom4j egy nyílt forráskódú keretrendszer az XML feldolgozásához, amely integrálva van az XPath-tal és teljes mértékben támogatja a DOM, SAX, JAXP és Java gyűjteményeket.

4.1. Maven-függőség

Hozzá kell adnunk a dom4j és a jaxen függőségeket a sajátunkhoz pom.xml a dom4j használatához projektünkben:

 org.dom4j dom4j 2.1.1 jaxen jaxen 1.2.0 

Az dom4j-ről többet megtudhatunk XML könyvtárak támogatási cikkünkben.

4.2. Használata org.dom4j.Element.addAttribute

dom4j felajánlja a Elem interfész egy XML elem absztrakciójaként. Használjuk a addAttribute módszer a vevő tulajdonság.

Lássuk, hogyan működik ez.

Először ki kell építenünk egy Dokumentum objektum az XML fájlból - ezúttal a SAXReader:

SAXReader xmlReader = új SAXReader (); Dokumentum bemenet = xmlReader.read (resourcePath); xmlReader.setFeature ("// apache.org/xml/features/disallow-doctype-decl", true); xmlReader.setFeature ("// xml.org/sax/features/external-general-entities", hamis); xmlReader.setFeature ("// xml.org/sax/features/external-parameter-entities", hamis);

Beállítottuk a további szolgáltatásokat annak érdekében, hogy megakadályozzuk az XXE-t.

A JAXP-hez hasonlóan XPath-kifejezéssel is kiválaszthatjuk a csomópontokat:

String expr = String.format ("// * [tartalmazza (@% s, '% s')]", attribútum, oldValue); XPath xpath = DocumentHelper.createXPath (expr); Csomópontok felsorolása = xpath.selectNodes (input);

Most megismételhetjük és frissíthetjük az attribútumot:

mert (int i = 0; i <csomópontok.méret (); i ++) {Elem elem = (Elem) csomópontok.get (i); element.addAttribute (attribútum, newValue); }

Vegye figyelembe, hogy ezzel a módszerrel, ha már létezik attribútum az adott névhez, akkor az kicserélődik. Ellenkező esetben hozzáadódik.

Az eredmények kinyomtatásához újra felhasználhatjuk az előző JAXP szakasz kódját.

5. A jOOX használata

A jOOX (jOOX objektum-orientált XML) a org.w3c.dom csomag, amely lehetővé teszi az XML dokumentumok gördülékeny létrehozását és manipulálását, ahol a DOM szükséges, de túl részletes. A jOOX csak az alapul szolgáló dokumentumot tekeri, és a DOM javítására használható, nem pedig alternatívaként.

5.1. Maven-függőség

Hozzá kell adnunk a függőséget a sajátunkhoz pom.xml hogy a jOOX-ot felhasználjuk projektünkben.

Java 9+ verzióval történő használatra használhatjuk:

 org.jooq joox 1.6.2 

Vagy Java 6+ verzióval:

 org.jooq joox-java-6 1.6.2 

Megtalálhatjuk a joox és joox-java-6 a Maven Central adattárban.

5.2. Használata org.w3c.dom.Element.setAttribute

Maga a jOOX API a jQuery ihlette, amint azt az alábbi példákban láthatjuk. Nézzük meg, hogyan kell használni.

Először be kell töltenünk a Dokumentum:

DocumentBuilder builder = JOOX.builder (); Dokumentumbevitel = builder.parse (resourcePath);

Most ki kell választanunk:

$ = $ (Input) egyezés;

A kiválasztásához ügyfélelem, használhatjuk a megtalálja metódus vagy XPath kifejezés. Mindkét esetben megkapjuk a hozzá illő elemek listáját.

Lássuk a megtalálja módszer működés közben:

$ .find ("to") .get () .stream () .forEach (e -> e.setAttribute (attribútum, newValue));

Ahhoz, hogy az eredmény a Húr, egyszerűen hívnunk kell a toString () módszer:

$ .toString ();

6. Benchmark

E könyvtárak teljesítményének összehasonlításához JMH referenciaértéket használtunk.

Lássuk az eredményeket:

| Benchmark Mode Cnt Score Hibaegységek | | ------------------------------------------------- ------------------- | | AttributeBenchMark.dom4jBenchmark átlag 5 0.150 ± 0.003 ms / op | | AttributeBenchMark.jaxpBenchmark átlag 5 0.166 ± 0.003 ms / op | | AttributeBenchMark.jooxBenchmark átlag 5 0,230 ± 0,033 ms / op |

Mint láthatjuk, ehhez a felhasználási esethez és megvalósításunkhoz a dom4j és a JAXP jobb pontszámot mutat, mint a jOOX.

7. Következtetés

Ebben a gyors bemutatóban bemutattuk, hogyan lehet módosítani az XML attribútumokat JAXP, dom4j és jOOX használatával. Ezenkívül JMH referenciaértékkel mértük e könyvtárak teljesítményét.

Szokás szerint az itt látható összes kódminta elérhető a GitHubon.