Programování

Zpracování XML dokumentů v Javě pomocí XPath a XSLT

Extensible Markup Language (XML) je v současné době rozhodně jednou z nejžhavějších technologií. I když koncept značkovacích jazyků není nový, XML se zdá obzvláště atraktivní pro programátory Java a Internetu. Rozhraní Java API pro analýzu XML (JAXP; viz zdroje), které bylo nedávno definováno prostřednictvím procesu Java Community Process, slibuje poskytnout společné rozhraní pro přístup k dokumentům XML. W3C definoval takzvaný Document Object Model (DOM), který poskytuje standardní rozhraní pro práci s dokumentem XML v hierarchii stromů, zatímco Simple API for XML (SAX) umožňuje programu analyzovat dokument XML postupně na základě na modelu zpracování událostí. Oba tyto standardy (SAX je de facto standard) doplňují JAXP. Společně tyto tři API poskytují dostatečnou podporu pro práci s XML dokumenty v Javě a jejich použití popisuje řada knih na trhu.

Tento článek představuje způsob zpracování dokumentů XML, který přesahuje standardní rozhraní API jazyka Java pro manipulaci s XML. Uvidíme, že v mnoha případech XPath a XSLT poskytují jednodušší a elegantnější způsoby řešení problémů s aplikacemi. V některých jednoduchých ukázkách porovnáme čisté řešení Java / XML s řešením, které využívá XPath a / nebo XSLT.

XSLT i XPath jsou součástí specifikace jazyka XSL (Extensible Stylesheet Language) (viz zdroje). XSL se skládá ze tří částí: samotná specifikace jazyka XSL, XSL Transformations (XSLT) a XML Path Language (XPath). XSL je jazyk pro transformaci dokumentů XML; obsahuje definici - Formátování objektů - způsobu formátování dokumentů XML pro prezentaci. XSLT určuje slovník pro transformaci jednoho dokumentu XML do jiného. XSLT můžete považovat za XSL mínus formátovací objekty. Jazyk XPath adresuje konkrétní části dokumentů XML a je určen k použití v rámci šablony stylů XSLT.

Pro účely tohoto článku se předpokládá, že znáte základy XML a XSLT a také rozhraní API DOM. (Informace a návody k těmto tématům najdete v části Zdroje.)

Poznámka: Ukázky kódu tohoto článku byly kompilovány a testovány pomocí analyzátoru XML Apache Xerces a procesoru Apache Xalan XSL (viz Zdroje).

Problém

Mnoho článků a článků zabývajících se XML uvádí, že je dokonalým prostředkem k dosažení dobré designové praxe v oblasti webového programování: vzor Model-View-Controller (MVC), nebo, jednodušeji, oddělení aplikačních dat od prezentačních. . Pokud jsou data aplikace formátována v XML, lze je snadno svázat - obvykle v servletu nebo na Java ServerPage - například se šablonami HTML pomocí šablony stylů XSL.

Ale XML může udělat mnohem víc než jen pomoci s oddělením pohledu modelu pro frontend aplikace. V současné době pozorujeme stále více rozšířené používání komponent (například komponent vyvinutých pomocí standardu EJB), které lze použít k sestavení aplikací, což zvyšuje produktivitu vývojářů. Opakovanou použitelnost komponent lze zlepšit formátováním dat, s nimiž se komponenty vyrovnávají standardním způsobem. Ve skutečnosti můžeme očekávat, že uvidíme stále více a více publikovaných komponent, které k popisu svých rozhraní používají XML.

Protože data ve formátu XML jsou jazykově neutrální, stanou se použitelnými v případech, kdy klient dané aplikační služby není znám, nebo pokud nesmí mít na serveru žádné závislosti. Například v prostředích B2B nemusí být pro dvě strany přijatelné mít závislosti na konkrétních rozhraních objektů Java pro jejich výměnu dat. Tyto technologie řeší nové technologie, jako je protokol SOAP (Simple Object Access Protocol) (viz zdroje).

Všechny tyto případy mají jednu společnou věc: data jsou uložena v dokumentech XML a musí s nimi manipulovat aplikace. Například aplikace, která používá různé komponenty od různých dodavatelů, bude pravděpodobně muset změnit strukturu dat (XML) tak, aby vyhovovala potřebám aplikace nebo dodržovala daný standard.

Kód napsaný pomocí výše zmíněných rozhraní Java API by to určitě udělal. Kromě toho je k dispozici stále více nástrojů, pomocí kterých můžete z dokumentu XML vytvořit prostředí JavaBean a naopak, což usnadňuje zpracování dat z programu Java. V mnoha případech však aplikace nebo alespoň její část zpracovává pouze jeden nebo více dokumentů XML jako vstup a převádí je do jiného formátu XML jako výstup. Použití stylů v těchto případech je schůdnou alternativou, jak uvidíme dále v tomto článku.

Pomocí XPath vyhledejte uzly v dokumentu XML

Jak je uvedeno výše, jazyk XPath se používá k vyhledání určitých částí dokumentu XML. Jako takový je určen k použití v šabloně stylů XSLT, ale nic nám nebrání v použití v našem programu Java, abychom se vyhnuli zdlouhavé iteraci nad hierarchií prvků DOM. Opravdu můžeme nechat procesor XSLT / XPath dělat práci za nás. Pojďme se podívat na to, jak to funguje.

Předpokládejme, že máme aplikační scénář, ve kterém je uživateli předán zdrojový dokument XML (pravděpodobně po zpracování pomocí šablony stylů). Uživatel provádí aktualizace dat a z důvodu úspory šířky pásma sítě odesílá zpět do aplikace pouze aktualizované záznamy. Aplikace vyhledá fragment XML ve zdrojovém dokumentu, který je třeba aktualizovat, a nahradí ho novými daty.

Vytvoříme malý vzorek, který vám pomůže pochopit různé možnosti. V tomto příkladu předpokládáme, že aplikace se zabývá záznamy adres v adresář. Vzorek adresář dokument vypadá takto:

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

Aplikace (možná, i když ne nutně, servlet) uchovává instanci adresář v paměti jako DOM Dokument objekt. Když uživatel změní adresu, rozhraní aplikace ji odešle pouze aktualizovanou živel.

The prvek se používá k jedinečné identifikaci adresy; slouží jako primární klíč. To by pro skutečnou aplikaci nemělo velký smysl, ale děláme to proto, aby to bylo jednoduché.

Nyní musíme napsat nějaký Java kód, který nám pomůže identifikovat prvek ve zdrojovém stromu, který je třeba nahradit aktualizovaným prvkem. The findAddress () níže uvedená metoda ukazuje, jak toho lze dosáhnout. Vezměte prosím na vědomí, že aby byl vzorek krátký, vynechali jsme příslušné zpracování chyb.

public Node findAddress (název řetězce, zdroj dokumentu) {Element root = source.getDocumentElement (); NodeList nl = root.getChildNodes (); // opakujte všechny uzly adresy a najděte ten, který má správného adresáta (int i = 0; i

Výše uvedený kód lze s největší pravděpodobností optimalizovat, ale je zřejmé, že iterace nad stromem DOM může být zdlouhavá a náchylná k chybám. Nyní se podívejme na to, jak lze lokalizovat cílový uzel pomocí jednoduchého příkazu XPath. Prohlášení může vypadat takto:

// adresa [dítě :: adresát [text () = 'Jim Smith']] 

Nyní můžeme přepsat naši předchozí metodu. Tentokrát použijeme příkaz XPath k vyhledání požadovaného uzlu:

public Node findAddress (název řetězce, zdroj dokumentu) vyvolá výjimku {// je třeba znovu vytvořit několik pomocných objektů XMLParserLiaison xpathSupport = new XMLParserLiaisonDefault (); XPathProcessor xpathParser = nový XPathProcessorImpl (xpathSupport); PrefixResolver prefixResolver = nový PrefixResolverDefault (source.getDocumentElement ()); // vytvořte XPath a inicializujte jej XPath xp = new XPath (); Řetězec xpString = "// adresa [dítě :: adresát [text () = '" + jméno + "']]]"; xpathParser.initXPath (xp, xpString, prefixResolver); // nyní spusťte příkaz XPath select XObject list = xp.execute (xpathSupport, source.getDocumentElement (), prefixResolver); // vrátí výsledný uzel zpětný seznam.nodeset (). item (0); } 

Výše uvedený kód nemusí vypadat mnohem lépe než předchozí pokus, ale většina obsahu této metody mohla být zapouzdřena ve třídě pomocníka. Jedinou částí, která se mění znovu a znovu, je skutečný výraz XPath a cílový uzel.

To nám umožňuje vytvořit XPathHelper třída, která vypadá takto:

import org.w3c.dom. *; import org.xml.sax. *; importovat org.apache.xalan.xpath. *; importovat org.apache.xalan.xpath.xml. *; veřejná třída XPathHelper {XMLParserLiaison xpathSupport = null; XPathProcessor xpathParser = null; PrefixResolver prefixResolver = null; XPathHelper () {xpathSupport = new XMLParserLiaisonDefault (); xpathParser = nový XPathProcessorImpl (xpathSupport); } public NodeList processXPath (String xpath, Node target) thws SAXException {prefixResolver = new PrefixResolverDefault (target); // vytvořte XPath a inicializujte jej XPath xp = new XPath (); xpathParser.initXPath (xp, xpath, prefixResolver); // nyní proveďte příkaz XPath select XObject list = xp.execute (xpathSupport, target, prefixResolver); // vrátí výsledný uzel zpětný seznam.nodeset (); }} 

Po vytvoření třídy pomocníka můžeme znovu přepsat naši vyhledávací metodu, která je nyní velmi krátká:

public Node findAddress (název řetězce, zdroj dokumentu) vyvolá výjimku {XPathHelper xpathHelper = nový XPathHelper (); NodeList nl = xpathHelper.processXPath ("// adresa [dítě :: adresát [text () = '" + jméno + "']]" ", source.getDocumentElement ()); vrátit nl.item (0); } 

Pomocnou třídu lze nyní použít, kdykoli je třeba v daném dokumentu XML umístit uzel nebo sadu uzlů. Skutečný příkaz XPath lze dokonce načíst z externího zdroje, takže je možné provádět změny za chodu, pokud se změní struktura zdrojového dokumentu. V tomto případě není nutná žádná kompilace.

Zpracovávejte dokumenty XML pomocí šablon stylů XSL

V některých případech má smysl outsourcovat celé zpracování dokumentu XML na externí šablonu stylů XSL, což je proces v některých ohledech podobný použití XPath, jak je popsáno v předchozí části. Pomocí šablon stylů XSL můžete vytvořit výstupní dokument výběrem uzlů ze vstupního dokumentu a sloučením jejich obsahu s obsahem šablony stylů na základě pravidel vzoru.

Pokud aplikace změní strukturu a obsah dokumentu XML a vytvoří nový dokument, může být lepší a snazší použít šablonu stylů k práci, než psát program Java, který dělá stejnou práci. Šablona stylů je s největší pravděpodobností uložena v externím souboru, což vám umožňuje měnit ji za běhu, aniž byste ji museli překompilovat.

Například bychom mohli dokončit zpracování pro adresář Ukázka vytvořením šablony stylů, která sloučí mezipaměťovou verzi souboru adresář s aktualizovaným, čímž vytvoříte nový dokument s aktualizacemi v něm.

Zde je ukázka takové šablony stylů:

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