Práca s XML v Groovy

1. Úvod

Groovy poskytuje značné množstvo metód určených na prechádzanie a manipuláciu s obsahom XML.

V tomto tutoriáli si ukážeme, ako na to pridávať, upravovať alebo mazať prvky z XML v aplikácii Groovy pomocou rôznych prístupov. Ukážeme tiež, ako na to vytvorte štruktúru XML od nuly.

2. Definovanie modelu

Definujme štruktúru XML v našom adresári zdrojov, ktorú použijeme v našich príkladoch:

  Prvé kroky v prostredí Java Siena Kerr 1. 12. 2018 Ukotvenie vašej aplikácie SpringBoot Jonas Lugo 1. 12. 2018 Výukový program SpringBoot Daniele Ferguson 12. 06. 2018 Java 12 insights Siena Kerr 22. 7. 2018 

A prečítajte si to do InputStream premenná:

def xmlFile = getClass (). getResourceAsStream ("articles.xml")

3. XmlParser

Začnime skúmať tento prúd pomocou XmlParser trieda.

3.1. Čítanie

Čítanie a analýza súboru XML je pravdepodobne najbežnejšia operácia XML, ktorú vývojár bude musieť urobiť. The XmlParser poskytuje veľmi priame rozhranie určené presne na toto:

def articles = new XmlParser (). parse (xmlFile)

V tomto okamihu môžeme pristupovať k atribútom a hodnotám štruktúry XML pomocou výrazov GPath.

Poďme si teraz implementovať jednoduchý test pomocou Spocku, ktorý skontroluje, či je náš článkov objekt je správny:

def "Malo by sa súbor XML čítať správne" () {zadané: "Súbor XML", keď: "Na čítanie súboru sa používa program XmlParser" def articles = nový XmlParser (). parse (xmlFile) potom: "Články XML sa načítajú správne". * '.size () == 4 articles.article [0] .author.firstname.text () == "Siena" articles.article [2].' release-date'.text () == "2018-06- 12 "articles.article [3] .title.text () ==" Štatistiky Java 12 "articles.article.find {it.author. '@ Id'.text () ==" 3 "} .author.firstname. text () == "Daniele"}

Aby sme pochopili, ako získať prístup k hodnotám XML a ako používať výrazy GPath, zamerajme sa na chvíľu na vnútornú štruktúru výsledku XmlParser # analýza prevádzka.

The článkov objekt je inštanciou groovy.util.Node. Každý Uzol sa skladá z mena, mapy atribútov, hodnoty a rodiča (ktorý môže byť buď nulový alebo iný Uzol).

V našom prípade hodnota článkov je a groovy.util.NodeList inštancia, ktorá je triedou obálky pre zbierku Uzols. The NodeList rozširuje java.util.ArrayList trieda, ktorá poskytuje extrakciu prvkov indexom. Ak chcete získať hodnotu reťazca a Uzol, používame groovy.util.Node # text ().

Vo vyššie uvedenom príklade sme predstavili niekoľko výrazov GPath:

  • articles.article [0] .autor.firstname - získajte krstné meno autora pre prvý článok - články.článok [n] by mal priamy prístup k nth článok
  • ‘*' - získať zoznam článokDeti - to je ekvivalent groovy.util.Node # deti ()
  • autor.'@id ' - dostať autor elementov id atribút - autor.'@attributeName ' pristupuje k hodnote atribútu podľa jeho názvu (ekvivalenty sú: autor [„@ id“] a [chránené e-mailom])

3.2. Pridanie uzla

Podobne ako v predchádzajúcom príklade, poďme najskôr načítať obsah XML do premennej. Toto nám umožní definovať nový uzol a pridať ho do nášho zoznamu článkov pomocou groovy.util.Node # pridať.

Poďme teraz implementovať test, ktorý preukáže náš zmysel:

def "Mal by pridať uzol do existujúceho xml pomocou NodeBuilder" () {given: "objekt XML" def articles = new XmlParser (). parse (xmlFile) when: "Adding node to xml" def articleNode = new NodeBuilder (). article ( id: '5') {title ('Stručné prechádzanie XML')) autor {firstname ('Martin') lastname ('Schmidt')} 'release-date' ('2019-05-18')} articles.append (articleNode) potom: „Uzol je správne pridaný do xml“ článkov. '*'. size () == 5 articles.article [4] .title.text () == "Prechádzanie XML v skratke"}

Ako vidíme na vyššie uvedenom príklade, proces je dosť priamy.

Všimnime si tiež, že sme použili groovy.util.NodeBuilder, čo je čistá alternatíva k použitiu Uzol konštruktér pre našu Uzol definícia.

3.3. Úprava uzla

Hodnoty uzlov môžeme upraviť aj pomocou XmlParser. Aby sme to mohli urobiť, znova analyzujme obsah súboru XML. Ďalej môžeme upraviť uzol obsahu zmenou hodnotu pole Uzol objekt.

Pamätajme na to XmlParser používa výrazy GPath, vždy načítame inštanciu súboru NodeList, aby sme mohli upraviť prvý (a jediný) prvok, musíme k nemu pristupovať pomocou jeho indexu.

Poďme skontrolovať naše predpoklady napísaním rýchleho testu:

def "Mal by upraviť uzol" () {given: "objekt XML" def articles = new XmlParser (). parse (xmlFile) when: "Zmena hodnoty jedného z uzlov" articles.article.each {it.'release-date '[0] .value = "2019-05-18"} potom: "XML je aktualizovaný" articles.article.findAll {it.'release-date'.text ()! = "2019-05-18"}. je prázdny() }

Vo vyššie uvedenom príklade sme tiež použili rozhranie Groovy Collections API na prechod cez NodeList.

3.4. Výmena uzla

Ďalej sa pozrime, ako nahradiť celý uzol namiesto úpravy iba jednej z jeho hodnôt.

Podobne ako pri pridávaní nového prvku použijeme NodeBuilder pre Uzol definíciu a potom nahradiť jeden z existujúcich uzlov v ňom pomocou groovy.util.Node # replaceNode:

def "Mal by nahradiť uzol" () {given: "objekt XML" def articles = new XmlParser (). parse (xmlFile) when: "Adding node to xml" def articleNode = new NodeBuilder (). article (id: '5' ) {title ('Stručné prehľadávanie XML')) autor {meno ('Martin') priezvisko ('Schmidt')} 'dátum vydania' ('2019-05-18')} articles.article [0] .replaceNode (articleNode) potom: „Uzol je správne pridaný do xml“ článkov. '*'. size () == 4 articles.article [0] .title.text () == "Prechádzanie XML v skratke"}

3.5. Vymazanie uzla

Vymazanie uzla pomocou XmlParser je dosť zložité. Napriek tomu Uzol trieda poskytuje odstrániť (uzol dieťa) metóda, vo väčšine prípadov by sme ju nepoužili sami.

Namiesto toho si ukážeme, ako odstrániť uzol, ktorého hodnota spĺňa danú podmienku.

V predvolenom nastavení je prístup k vnoreným prvkom pomocou reťazca Node.NodeList referencie vráti kópiu zodpovedajúcich detských uzlov. Z tohto dôvodu nemôžeme používať java.util.NodeList # removeAll metóda priamo na našom článok zbierka.

Ak chceme uzol vymazať pomocou predikátu, musíme najskôr nájsť všetky uzly, ktoré zodpovedajú našej podmienke, a potom cez ne prechádzať a vyvolať java.util.Node # odstrániť metóda na rodičovi zakaždým.

Implementujme test, ktorý odstráni všetky články, ktorých autor má iné ID ako 3:

def "Mal by odstrániť článok z xml" () {given: "objekt XML" def articles = new XmlParser (). parse (xmlFile) when: "Odstránenie všetkých článkov okrem tých s id == 3" articles.article .findAll { it.author. '@ id'.text ()! = "3"} .each {articles.remove (it)} potom: "Zostáva iba jeden článok" articles.children (). size () == 1 articles.article [0] .author. '@ id'.text () == "3"}

Ako vidíme, v dôsledku našej operácie odstránenia sme dostali štruktúru XML, ktorá obsahuje iba jeden článok a jeho ID je 3.

4. XmlSlurper

Groovy tiež poskytuje ďalšiu triedu venovanú práci s XML. V tejto časti si ukážeme, ako čítať a manipulovať so štruktúrou XML pomocou XmlSlurper.

4.1. Čítanie

Rovnako ako v našich predchádzajúcich príkladoch, začnime analýzou štruktúry XML zo súboru:

def "Malo by sa súbor XML správne čítať" () {zadané: "Súbor XML", keď: "Na čítanie súboru sa používa XmlSlurper" def articles = nový XmlSlurper (). parse (xmlFile) potom: "Články XML sa načítajú správne". '* '.size () == 4 articles.article [0] .author.firstname == "Siena" articles.article [2].' release-date '== "12.06.2018" articles.article [3] .title == "Štatistiky Java 12" articles.article.find {it.author.'@id '== "3"} .author.firstname == "Daniele"}

Ako vidíme, rozhranie je identické s rozhraním XmlParser. Avšak výstupná štruktúra používa groovy.util.slurpersupport.GPathResult, čo je obálka triedy pre Uzol. GPathResult poskytuje zjednodušené definície metód, ako napríklad: rovná sa () a natiahnuť() zabalením Uzol # text (). Vďaka tomu môžeme polia a parametre čítať priamo iba pomocou ich mien.

4.2. Pridanie uzla

Pridanie a Uzol je tiež veľmi podobné používaniu XmlParser. V tomto prípade však groovy.util.slurpersupport.GPathResult # appendNode poskytuje metódu, ktorá berie inštanciu z java.lang.Objekt ako argument. Vďaka tomu môžeme nové zjednodušiť Uzol definície podľa rovnakého dohovoru zavedeného UzolStaviteľ:

def "Mal by pridať uzol do existujúceho xml" () {given: "objekt XML" def articles = new XmlSlurper (). parse (xmlFile) when: "Adding node to xml" articles.appendNode {article (id: '5') {title ('Stručný prehľad XML)' autor {firstname ('Martin') lastname ('Schmidt')} 'release-date' ('2019-05-18')}} articles = new XmlSlurper (). parseText (XmlUtil.serialize (articles)) then: "Uzol je správne pridaný do xml" článkov. '*'. Size () == 5 articles.article [4] .title == "Prechádzanie XML v skratke"}

V prípade, že potrebujeme upraviť štruktúru nášho XML pomocou XmlSlurper, musíme znova inicializovať naše článkov objekt vidieť výsledky. Toho môžeme dosiahnuť kombináciou groovy.util.XmlSlurper # parseText a groovy.xmlXmlUtil # serialize metódy.

4.3. Úprava uzla

Ako sme už spomínali, GPathResult zavádza zjednodušený prístup k manipulácii s údajmi. To je povedané, na rozdiel od XmlSlurper, môžeme upraviť hodnoty priamo pomocou názvu uzla alebo názvu parametra:

def "Mal by upraviť uzol" () {dané: "objekt XML" def articles = new XmlSlurper (). parse (xmlFile), keď: "Zmena hodnoty jedného z uzlov" articles.article.each {it.'release-date '= "2019-05-18"} potom: "XML je aktualizovaný" articles.article.findAll {it.'release-date'! = "2019-05-18"} .isEmpty ()}

Všimnime si, že keď upravíme iba hodnoty objektu XML, nemusíme znova analyzovať celú štruktúru.

4.4. Výmena uzla

Teraz prejdime k nahradeniu celého uzla. Opäť platí, že GPathResult prichádza na pomoc. Uzol môžeme ľahko vymeniť pomocou groovy.util.slurpersupport.NodeChild # replaceNode, ktorá sa rozširuje GPathResult a riadi sa rovnakou konvenciou používania Objekt hodnoty ako argumenty:

def "Mal by nahradiť uzol" () {given: "objekt XML" def articles = new XmlSlurper (). parse (xmlFile) when: "Replacing node" articles.article [0] .replaceNode {article (id: '5') {title ('Stručný prehľad XML)' autor {firstname ('Martin') lastname ('Schmidt')} 'release-date' ('2019-05-18')}} articles = new XmlSlurper (). parseText (XmlUtil.serialize (articles)) then: "Uzol je správne nahradený" articles. '*'. Size () == 4 articles.article [0] .title == "Prechádzanie XML v skratke"}

Rovnako ako v prípade pridávania uzla, upravujeme štruktúru XML, takže ho musíme znova analyzovať.

4.5. Vymazanie uzla

Ak chcete odstrániť uzol pomocou XmlSlurper, môžeme znovu použiť groovy.util.slurpersupport.NodeChild # replaceNode jednoducho zadaním prázdneho Uzol definícia:

def "Mal by odstrániť článok z xml" () {given: "objekt XML" def articles = new XmlSlurper (). parse (xmlFile) when: "Odstránenie všetkých článkov okrem tých s id == 3" articles.article .findAll { it.author.'@id '! = "3"} .replaceNode {} articles = new XmlSlurper (). parseText (XmlUtil.serialize (articles)) potom: "Už zostáva iba jeden článok" articles.children (). size () == 1 articles.article [0] .author. '@ id' == "3"}

Opäť platí, že zmena štruktúry XML vyžaduje opätovnú inicializáciu našej článkov objekt.

5. XmlParser vs XmlSlurper

Ako sme ukázali v našich príkladoch, zvyklosti XmlParser a XmlSlurper sú si dosť podobné. U oboch môžeme dosiahnuť viac-menej rovnaké výsledky. Niektoré rozdiely medzi nimi však môžu nakloniť váhy k jednej alebo druhej.

Po prvé,XmlParser vždy analyzuje celý dokument do štruktúry DOM-ish. Z tohto dôvodu môžeme súčasne čítať a zapisovať do nej. To isté nemôžeme urobiť XmlSlurper keďže lenivejšie hodnotí cesty. Ako výsledok, XmlParser môže spotrebovať viac pamäte.

Na druhej strane, XmlSlurper používa jasnejšie definície, vďaka ktorým je práca s ním jednoduchšia. Musíme si to tiež pamätať akékoľvek štrukturálne zmeny vykonané pomocou XML XmlSlurper vyžadujú reinicializáciu, čo môže mať neprijateľný vplyv na výkon v prípade vykonania mnohých zmien jedna za druhou.

Rozhodnutie, ktorý nástroj použijete, by sa malo robiť opatrne a závisí výlučne od prípadu použitia.

6. MarkupBuilder

Okrem čítania a manipulácie so stromom XML poskytuje Groovy aj nástroje na vytvorenie dokumentu XML od nuly. Poďme si teraz vytvoriť dokument pozostávajúci z prvých dvoch článkov z nášho prvého príkladu pomocou groovy.xml.MarkupBuilder:

def "Malo by sa správne vytvoriť XML" () {dané: "Štruktúry uzlov", keď: "Použitie MarkupBuilderTestu na vytvorenie štruktúry XML" def writer = nový StringWriter () nový MarkupBuilder (spisovateľ) .articles {article {title ('Prvé kroky v Jave ') author (id:' 1 ') {firstname (' Siena ') lastname (' Kerr ')}' release-date '(' 2018-12-01 ')} article {title (' Dockerize your SpringBoot application ') autor (id: '2') {firstname ('Jonas') lastname ('Lugo')} 'release-date' ('2018-12-01')}} potom: "Xml je správne vytvorený" XmlUtil.serialize ( writer.toString ()) == XmlUtil.serialize (xmlFile.text)}

Na uvedenom príklade to vidíme MarkupBuilder používa rovnaký prístup pre Uzol definície, ktoré sme použili s NodeBuilder a GPathResult predtým.

Na porovnanie výstupu z MarkupBuilder s očakávanou štruktúrou XML sme použili groovy.xml.XmlUtil # serialize metóda.

7. Záver

V tomto článku sme preskúmali viac spôsobov manipulácie so štruktúrami XML pomocou programu Groovy.

Pozreli sme sa na príklady syntaktickej analýzy, pridania, úpravy, nahradenia a odstránenia uzlov pomocou dvoch tried, ktoré poskytuje Groovy: XmlParser a XmlSlurper. Diskutovali sme tiež o rozdieloch medzi nimi a ukázali sme, ako by sme mohli zostaviť strom XML od nuly pomocou MarkupBuilder.

Úplný kód použitý v tomto článku je ako vždy k dispozícii na stránkach GitHub.


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