Programiranje

Obdelava dokumentov XML v Javi z uporabo XPath in XSLT

Razširljivi označevalni jezik (XML) je zagotovo ena najbolj vročih tehnologij v tem trenutku. Koncept označevalnih jezikov sicer ni nov, vendar se zdi XML še posebej privlačen za programerje Java in Internet. Java API za razčlenjevanje XML (JAXP; glej vire), ki je bil pred kratkim opredeljen s postopkom Java Community, obljublja, da bo zagotovil skupni vmesnik za dostop do dokumentov XML. W3C je opredelil tako imenovani objektni model dokumenta (DOM), ki zagotavlja standardni vmesnik za delo z dokumentom XML v drevesni hierarhiji, medtem ko Simple API for XML (SAX) omogoča programu, da zaporedno analizira dokument XML na modelu obdelave dogodkov. Oba standarda (SAX je dejanski standard) dopolnjujeta JAXP. Ti trije API-ji skupaj zagotavljajo zadostno podporo za obravnavo dokumentov XML v Javi, številne knjige na trgu pa opisujejo njihovo uporabo.

Ta članek predstavlja način za obdelavo dokumentov XML, ki presega standardne API-je Java za manipulacijo XML. Videli bomo, da v mnogih primerih XPath in XSLT ponujata preprostejše in elegantnejše načine reševanja aplikacijskih težav. V nekaterih preprostih vzorcih bomo primerjali čisto rešitev Java / XML z rešitvijo, ki uporablja XPath in / ali XSLT.

Tako XSLT kot XPath sta del specifikacije razširljivega jezika slogovnega lista (XSL) (glejte Viri). XSL je sestavljen iz treh delov: sama specifikacija jezika XSL, pretvorbe XSL (XSLT) in jezik poti XML (XPath). XSL je jezik za pretvorbo dokumentov XML; vključuje definicijo - Oblikovanje predmetov - načina oblikovanja dokumentov XML za predstavitev. XSLT določa besednjak za pretvorbo enega dokumenta XML v drugega. XSLT lahko štejete za XSL minus oblikovalni predmeti. Jezik XPath naslavlja določene dele dokumentov XML in je namenjen uporabi znotraj stilskega lista XSLT.

Za namene tega članka se domneva, da poznate osnove XML in XSLT ter API-je DOM. (Za informacije in vadnice o teh temah glejte Viri.)

Opomba: Vzorci kode v tem članku so bili zbrani in preizkušeni z razčlenjevalnikom Apache Xerces XML in procesorjem Apache Xalan XSL (glejte Viri).

Težava

Številni članki in članki, ki se ukvarjajo z XML, trdijo, da je popolno sredstvo za doseganje dobre prakse oblikovanja pri spletnem programiranju: vzorec Model-View-Controller (MVC) ali, poenostavljeno rečeno, ločevanje aplikacijskih podatkov od predstavitvenih . Če so podatki aplikacije formatirani v XML, jih je mogoče zlahka vezati - navadno v strežniku ali Java ServerPage - na, denimo, predloge HTML s pomočjo slogovnega lista XSL.

Toda XML lahko naredi veliko več kot zgolj pomoč pri ločevanju od pogleda modela do prednjega dela aplikacije. Trenutno opažamo vse bolj razširjeno uporabo komponent (na primer komponent, razvitih po standardu EJB), ki jih lahko uporabimo za sestavljanje aplikacij in s tem povečamo storilnost razvijalcev. Ponovno uporabo komponent je mogoče izboljšati s standardnim formatiranjem podatkov, s katerimi se komponente ukvarjajo. Dejansko lahko pričakujemo vse več objavljenih komponent, ki uporabljajo XML za opis svojih vmesnikov.

Ker so podatki v obliki zapisa XML jezikovno nevtralni, postanejo uporabni v primerih, ko odjemalec določene aplikacijske storitve ni znan ali kadar ne sme biti odvisen od strežnika. Na primer, v okoljih B2B morda ni sprejemljivo, da imata dve strani odvisnosti od konkretnih vmesnikov predmetov Java za izmenjavo podatkov. Nove tehnologije, kot je protokol enostavnega dostopa do objektov (SOAP) (glejte Viri), obravnavajo te zahteve.

Vsem tem primerom je skupno eno: podatki so shranjeni v dokumentih XML in jih mora aplikacija upravljati. Na primer, aplikacija, ki uporablja različne komponente različnih ponudnikov, bo najverjetneje morala spremeniti strukturo podatkov (XML), da bo ustrezala potrebam aplikacije ali se držala določenega standarda.

Koda, napisana z zgoraj omenjenimi API-ji Java, bi to zagotovo storila. Poleg tega je na voljo vse več orodij, s katerimi lahko dokument XML spremenite v JavaBean in obratno, kar olajša obdelavo podatkov v programu Java. Vendar v mnogih primerih aplikacija ali vsaj njen del zgolj obdela enega ali več dokumentov XML kot vhodne podatke in jih kot izhodne podatke pretvori v drugačno obliko XML. Kot bomo videli kasneje v tem članku, je uporaba tabel slogi v teh primerih izvedljiva alternativa.

Uporabite XPath za iskanje vozlišč v dokumentu XML

Kot je navedeno zgoraj, se jezik XPath uporablja za iskanje določenih delov dokumenta XML. Kot taka naj bi jo uporabljala tabela s slogi XSLT, vendar nam nič ne preprečuje uporabe v našem programu Java, da bi se izognili dolgotrajni ponovitvi hierarhije elementov DOM. Dejansko lahko pustimo, da procesor XSLT / XPath opravi delo namesto nas. Oglejmo si, kako to deluje.

Predpostavimo, da imamo aplikacijski scenarij, v katerem je uporabniku predstavljen izvorni dokument XML (morda po obdelavi s slogi). Uporabnik posodablja podatke in za prihranek pasovne širine omrežja pošlje samo posodobljene zapise v aplikacijo. Aplikacija išče fragment XML v izvornem dokumentu, ki ga je treba posodobiti, in ga nadomesti z novimi podatki.

Ustvarili bomo majhen vzorec, ki vam bo pomagal razumeti različne možnosti. Za ta primer domnevamo, da aplikacija obravnava zapise naslovov v datoteki imenik. Vzorec imenik dokument izgleda takole:

  John Smith 250 18th Ave SE Rochester MN 55902 Bill Morris 1234 Center Lane NW St. Paul MN 55123 

Aplikacija (morda, čeprav ne nujno, strežniški programček) hrani primerek datoteke imenik v spominu kot DOM Dokument predmet. Ko uporabnik spremeni naslov, mu vmesnik aplikacije pošlje samo posodobljen element.

The element se uporablja za enolično identifikacijo naslova; služi kot primarni ključ. Za resnično aplikacijo to ne bi imelo velikega smisla, vendar to počnemo tukaj, da stvari ostanejo preproste.

Zdaj moramo napisati nekaj Java kode, ki nam bo pomagala prepoznati element v izvornem drevesu, ki ga je treba zamenjati s posodobljenim elementom. The findAddress () spodnja metoda prikazuje, kako je to mogoče doseči. Upoštevajte, da smo zaradi kratkega vzorca izpustili ustrezno ravnanje z napakami.

javno vozlišče findAddress (ime niza, vir dokumenta) {Element root = source.getDocumentElement (); Seznam vozlišč nl = root.getChildNodes (); // prelistamo vsa naslovna vozlišča in poiščemo tisto, ki ima ustreznega naslovnika za (int i = 0; i

Zgornjo kodo bi lahko najverjetneje optimizirali, vendar je očitno, da je ponovitev drevesa DOM lahko dolgočasna in nagnjena k napakam. Zdaj pa poglejmo, kako lahko s pomočjo preprostega stavka XPath najdemo ciljno vozlišče. Izjava bi lahko izgledala takole:

// naslov [otrok :: naslovnik [text () = 'Jim Smith']] 

Zdaj lahko prepišemo prejšnjo metodo. Tokrat s pomočjo stavka XPath poiščemo želeno vozlišče:

javno vozlišče findAddress (ime niza, vir dokumenta) vrže izjemo {// treba je znova ustvariti nekaj pomožnih predmetov XMLParserLiaison xpathSupport = nov XMLParserLiaisonDefault (); XPathProcessor xpathParser = nov XPathProcessorImpl (xpathSupport); PrefixResolver prefixResolver = nov PrefixResolverDefault (source.getDocumentElement ()); // izdelamo XPath in ga inicializiramo XPath xp = new XPath (); String xpString = "// naslov [otrok :: naslovnik [besedilo () = '" + ime + "']]"; xpathParser.initXPath (xp, xpString, prefixResolver); // zdaj izvedemo stavek za izbiro XPath XObject list = xp.execute (xpathSupport, source.getDocumentElement (), prefixResolver); // vrnemo nastali vozlišče return list.nodeset (). item (0); } 

Zgornja koda morda ni videti veliko bolje kot v prejšnjem poskusu, vendar je večina vsebine te metode lahko vključena v pomožni razred. Edini del, ki se vedno znova spreminja, je dejanski izraz XPath in ciljno vozlišče.

To nam omogoča ustvarjanje XPathHelper razred, ki je videti takole:

uvoz org.w3c.dom. *; uvoz org.xml.sax. *; uvoz org.apache.xalan.xpath. *; uvoz org.apache.xalan.xpath.xml. *; javni razred XPathHelper {XMLParserLiaison xpathSupport = null; XPathProcessor xpathParser = null; PrefixResolver prefixResolver = null; XPathHelper () {xpathSupport = nov XMLParserLiaisonDefault (); xpathParser = nov XPathProcessorImpl (xpathSupport); } public NodeList processXPath (String xpath, Node target) thrws SAXException {prefixResolver = new PrefixResolverDefault (target); // izdelamo XPath in ga inicializiramo XPath xp = new XPath (); xpathParser.initXPath (xp, xpath, prefixResolver); // zdaj izvedemo stavek XPath select XObject list = xp.execute (xpathSupport, target, prefixResolver); // vrnemo dobljeni vozlišče return return.nodeset (); }} 

Po ustvarjanju pomožnega razreda lahko znova prepišemo našo iskalno metodo, ki je zdaj zelo kratka:

javno vozlišče findAddress (ime niza, vir dokumenta) vrže izjemo {XPathHelper xpathHelper = new XPathHelper (); NodeList nl = xpathHelper.processXPath ("// naslov [otrok :: naslovnik [besedilo () = '" + ime + "']]", source.getDocumentElement ()); vrnitev nl.item (0); } 

Razred pomočnikov je zdaj mogoče uporabiti, kadar je v določenem dokumentu XML treba najti vozlišče ali niz vozlišč. Dejanski stavek XPath je mogoče celo naložiti iz zunanjega vira, tako da se lahko spremembe spreminjajo sproti, če se spremeni struktura izvornega dokumenta. V tem primeru ni potrebno ponovno sestavljanje.

Obdelajte dokumente XML s tabelami stilov XSL

V nekaterih primerih je smiselno celotno obdelavo dokumenta XML oddati zunanjim izvajalcem v zunanji tabeli stilov XSL, kar je v nekaterih pogledih podobno kot uporaba XPath, kot je opisano v prejšnjem razdelku. S tabelami slogov XSL lahko ustvarite izhodni dokument tako, da izberete vozlišča v vhodnem dokumentu in združite njihovo vsebino z vsebino tabele na podlagi pravil vzorca.

Če aplikacija spremeni strukturo in vsebino dokumenta XML in ustvari nov dokument, je morda bolje in lažje uporabiti tabelo slogi za delo, namesto da bi napisali program Java, ki opravlja isto delo. Preglednica je najverjetneje shranjena v zunanji datoteki, kar vam omogoča, da jo lahko spremenite sproti, brez potrebe po ponovnem prevajanju.

Na primer, lahko izvedemo obdelavo za imenik vzorec z ustvarjanjem slogovnega lista, ki združuje predpomnjeno različico datoteke imenik s posodobljenim in tako ustvari nov dokument s posodobitvami v njem.

Tu je vzorec takega sloga:

   //mymachine.com/changed.xml 
$config[zx-auto] not found$config[zx-overlay] not found