Programovanie

XSLT kvitne s Javou

Už vás niekedy zaskočil zložitý problém s transformáciou XML, ktorý ste nedokázali vyriešiť len pomocou XSLT (Extensible Stylesheet Language Transformation)? Vezmime si napríklad jednoduchú šablónu so štýlmi filtra, ktorá vyberie iba tie uzly s dátumom skôr ako pred piatimi dňami. Počuli ste, že XSLT dokáže filtrovať dokumenty XML, takže ste zistili, že tento problém vyriešite okamžite. Prvou úlohou je získať dnešný dátum zo šablóny štýlov za predpokladu, že informácie nie sú obsiahnuté v pôvodnom dokumente XML. Túto úlohu bohužiaľ nemôžete dokončiť iba pomocou XSLT. V takejto situácii môžete svoj kód XSLT zjednodušiť a problém vyriešiť rýchlejšie pomocou rozšírenia Java.

Mnoho procesorov XSLT umožňuje nejaký typ rozširovacieho mechanizmu; vyžaduje to od nich špecifikácia. Vo svete Java a XML je najpoužívanejším procesorom XSLT otvorený procesor Apache Xalan. Xalan, napísaný v jazyku Java, umožňuje rozšírenie v prostredí Java. Mnoho vývojárov považuje rozšíriteľnosť Xalanu za silnú, pretože im umožňuje využívať svoje znalosti jazyka Java z kontextu štýlov. Zvážte spôsob, akým súbory JSP (JavaServer Pages), skriptá a vlastné značky pridávajú energiu do HTML. Rozšírenia Xalan dodávajú silu do štýlov rovnakým spôsobom: umožnením vývojárom Java prístup k ich obľúbenému nástroju Java.

V tomto článku ukážem, ako môžete používať Javu v rámci šablóny so štýlmi XSLT. Najskôr použijeme rozšíriteľnosť Xalanu na vytvorenie inštancie a použitie existujúcich tried v rámci JDK. Neskôr si ukážem, ako napísať funkciu rozšírenia XSLT, ktorá trvá a String argument a vráti fragment DOM (Document Object Model) do procesora štýlov.

XSLT je dôležité pre vývojárov J2EE (Java 2 Platform, Enterprise Edition), pretože úprava štýlov dokumentov XML sa stala operáciou na strane servera. Súčasťou špecifikácie J2EE (J2EE 2.6.11) sa stal aj JAXP (Java API pre spracovanie XML), ktorý obsahuje podporu pre motory XSLT. V počiatkoch bolo zámerom XSLT upraviť štýl XML na klientovi; väčšina aplikácií však upravuje formát XML pred jeho odoslaním klientovi. Pre vývojárov J2EE to znamená, že procesor XSLT bude s najväčšou pravdepodobnosťou bežať v rámci aplikačného servera.

Skôr ako budete pokračovať v tomto článku, upozorňujeme, že používanie rozšírení Java v šablónach štýlov XSLT zníži ich prenosnosť. Aj keď sú rozšírenia súčasťou špecifikácie XSLT, spôsob ich implementácie nie je. Ak vaše tabuľky štýlov fungujú na iných procesoroch ako Xalan, napríklad na šablóne štýlov programu Internet Explorer, mali by ste sa za každú cenu vyhnúť používaniu rozšírení.

Slabiny XSLT

Pretože XSLT má slabé miesta, ukážky XSLT sa ukazujú ako celkom užitočné. Nehovorím, že XSLT je zlý; jednoducho však neponúka najlepší nástroj na spracovanie všetkého v dokumente XML. Zvážte túto časť XML:

 Používanie XSLT nie je také ľahké, ako by ste si niektorí mysleli ... 

Predpokladajme, že vás šéf požiada, aby ste upravili šablónu štýlov tak, aby konvertovala všetky výskyty „nie je“ na „nie je“ a lokalizovala bežné štítky. XSLT určite poskytuje mechanizmus, ako niečo urobiť v tomto zmysle, však? Nesprávne. XSLT neposkytuje jednoduchý spôsob, ako nahradiť výskyt slova alebo vzoru v reťazci. To isté platí pre lokalizáciu. To však neznamená, že to nemožno urobiť so štandardnou syntaxou XSLT. Existujú spôsoby, ale nie sú to ani zďaleka také ľahké, ako by sme chceli. Ak naozaj chcete písať funkcie manipulácie s textom pomocou rekurzívnych šablón, buďte mojimi hosťami.

Hlavnou slabinou XSLT je spracovanie textu, ktoré sa zdá byť rozumné, pretože jeho účelom je vykreslenie XML. Pretože však obsah XML je iba text, XSLT vyžaduje dôkladnejšie zaobchádzanie s textom. Netreba dodávať, že návrhári štýlov vyžadujú z času na čas určitú rozšíriteľnosť. S Xalan poskytuje Java túto rozšíriteľnosť.

Používajte triedy JDK v rámci XSLT

Možno vás poteší, že nemusíte využívať žiadny Java kód, aby ste využili rozšíriteľnosť Xalanu. Keď používate Xalan, môžete vytvárať a vyvolávať metódy takmer pre akýkoľvek objekt Java. Pred použitím triedy Java musíte poskytnúť XSLT menný priestor pre to. Tento príklad deklaruje „java“ ako priestor názvov pre všetko v balíku Java alebo pod ním (t. j. celý JDK):

Teraz musíme niečo urobiť. Začnime s malým dokumentom XML:

 Java môže byť módou J. Burke 30. 11. 1997 

Boli ste požiadaní, aby ste tento XML upravili tak, aby sa názov zobrazoval veľkými písmenami. Vývojár nový v XSLT by jednoducho otvoril odkaz na XSLT a hľadal toUpper () funkcia; bola by však sklamaná, keby zistila, že referencii jeden chýba. The preložiť () Metóda je vaša najlepšia stávka, ale mám ešte lepšiu metódu: java.lang.String.toUpperCase (). Ak chcete použiť túto metódu, musíte vytvoriť inštanciu a String objekt s obsahom nadpisu. Takto môžete vytvoriť nový String inštancia s obsahom prvku title:

The názov atribút určuje popisovač vášho nového String inštancia. Vyvoláte konštruktor tak, že najskôr určíte priestor mien a zostávajúcu cestu k String trieda. Ako ste si mohli všimnúť, String chýba a Nový() metóda. Používaš Nový() skonštruovať objekt Java v Xalane; zodpovedá Java Nový kľúčové slovo. Argumenty uvedené v Nový() určiť verziu konštruktora, ktorá sa bude volať. Teraz, keď máte obsah nadpisu v prostredí Java String objekt, môžete použiť toUpperCase () metóda, napríklad takto:

To by sa ti na začiatku mohlo zdať čudné. Pri použití metód Java v konkrétnej inštancii je prvým argumentom inštancia, v ktorej chcete metódu vyvolať. Je zrejmé, že Xalan na zabezpečenie tejto schopnosti používa introspekciu.

Ďalej nájdete ďalší trik. Tu je ukážka toho, ako môžete emitovať dátum a čas kdekoľvek v šablóne štýlov pomocou java.lang.Date:

Tu je niečo, vďaka čomu bude každý, kto bude musieť lokalizovať všeobecnú šablónu štýlov medzi dvoma alebo viacerými jazykmi, deň. Môžeš použiť java.util.ResourceBundle lokalizovať doslovný text v šablóne so štýlmi. Pretože váš XML obsahuje autorskú značku, možno budete chcieť vytlačiť „Autor:“ vedľa mena osoby.

Jednou z možností je vytvoriť samostatnú šablónu so štýlmi pre každé miestne nastavenie, t. J. Jednu pre angličtinu, druhú pre čínštinu atď. Problémy spojené s týmto prístupom by mali byť zrejmé. Udržiavanie konzistentnosti viacerých verzií štýlov je časovo náročné. Musíte tiež upraviť svoju aplikáciu tak, aby vyberala správnu šablónu štýlov na základe miestneho nastavenia používateľa.

Namiesto duplikovania šablóny so štýlmi pre každý jazyk môžete využiť výhody lokalizačných funkcií jazyka Java. Lokalizácia pomocou a ResourceBundle dokazuje lepší prístup. V rámci XSLT načítajte ResourceBundle na začiatku vašich šablón štýlov, napríklad takto:

The ResourceBundle trieda očakáva nájdenie súboru s názvom Všeobecné.vlastnosti vo vašom CLASSPATH. Po vytvorení zväzku ho možno znova použiť v celej šablóne so štýlmi. Tento príklad načíta súbor autor zdroj:

Znova si všimnite zvláštny podpis metódy. Za normálnych okolností ResourceBundle.getString () trvá iba jeden argument; v rámci XSLT však musíte určiť aj objekt, pomocou ktorého chcete metódu vyvolať.

Napíšte svoje vlastné rozšírenia

V niektorých zriedkavých situáciách možno budete musieť napísať svoju vlastnú príponu XSLT vo forme funkcie rozšírenia alebo prvku rozšírenia. Budem diskutovať o vytvorení funkcie rozšírenia, čo je koncept, ktorý sa dá ľahko uchopiť. Akákoľvek funkcia rozšírenia Xalan môže brať reťazce ako vstupné a vratné reťazce do procesora XSLT. Môžu trvať aj vaše rozšírenia NodeLists alebo Uzols ako argumenty a vráti tieto typy procesoru XSLT. Použitím Uzols alebo NodeLists znamená, že môžete pridať k pôvodnému dokumentu XML funkciu rozšírenia, čo urobíme.

Jedným typom textovej položky, s ktorou sa často stretávate, je dátum; poskytuje skvelú príležitosť pre nové rozšírenie XSLT. Našou úlohou je upraviť štýl prvku článku tak, aby sa dátum vytlačil v nasledujúcom formáte:

Piatok, 30. novembra 200

Môže štandardný XSLT dokončiť vyššie uvedený dátum? XSLT môže dokončiť väčšinu úlohy. Ťažká je určiť skutočný deň. Jedným zo spôsobov, ako tento problém rýchlo vyriešiť, je použitie java.text.SimpleDate format class within an extension function to return a string formatted as we wish. Ale počkajte: všimnite si, že deň sa zobrazuje tučným písmom. Týmto sa vraciame k pôvodnému problému. Dôvod, prečo dokonca uvažujeme o rozšírenej funkcii, je ten, že pôvodný dokument XML nedokázal štruktúrovať dátum ako skupinu uzlov. Ak naša funkcia rozšírenia vráti reťazec, urobíme to stále je ťažké upraviť pole dňa inak ako zvyšok reťazca dátumu. Tu je užitočnejší formát, prinajmenšom z pohľadu návrhára XSLT:

  11 30 2001  

Teraz vytvoríme funkciu rozšírenia XSLT, pričom ako argument vezmeme reťazec a vrátime uzol XML v tomto formáte:

  30. novembra, piatok 2001 

Trieda, ktorá hostí našu funkciu rozšírenia, nič neimplementuje ani nerozširuje; zavoláme triedu DateFormatter:

public class DateFormatter {public static Node format (String date) {} 

Páni, príliš ľahké, hm? Na typ alebo rozhranie funkcie rozšírenia Xalan nie sú kladené absolútne žiadne požiadavky. Všeobecne platí, že väčšina funkcií rozšírenia bude trvať a String ako argument a vrátiť ďalší String. Ďalšie bežné vzory sú odosielanie alebo prijímanie org.w3c.dom.NodeLists alebo jednotlivec Uzols z funkcie rozšírenia, ako to urobíme. Podrobnosti o tom, ako sa typy Java prevádzajú na typy XSLT, nájdete v dokumentácii k systému Xalan.

Vo fragmente kódu vyššie formát () logika metódy sa rozpadá na dve časti. Najskôr musíme analyzovať reťazec dátumu z pôvodného dokumentu XML. Potom pomocou niektorých programovacích techník DOM vytvoríme a Uzol a vráťte ho do procesora XSLT. Telo nášho formát () implementácia metódy znie:

 Dokument doc = DocumentBuilderFactory.newInstance (). newDocumentBuilder (). newDocument (); Element dateNode = doc.createElement ("formatted-date"); SimpleDateFormat df = (SimpleDateFormat) DateFormat.getDateInstance (DateFormat.SHORT, miestne nastavenie); df.setLenient (true); Dátum d = df.parse (dátum); df.applyPattern ("MMMM"); addChild (dateNode, "month", df.format (d)); df.applyPattern ("EEEE"); addChild (dateNode, "deň v týždni", df.format (d)); df.applyPattern ("rrrr"); dateNode.setAttribute ("rok", df.format (d)); dátum vráteniaNode; 

dateNode bude obsahovať naše formátované hodnoty dátumu, ktoré sa vrátime do šablóny so štýlmi. Všimnite si, že sme to využili java.text.SimpleDateFormat () analyzovať dátum. To nám umožňuje plne využívať podporu dátumu v Jave vrátane jej lokalizačných funkcií. SimpleDateFormat spracováva číselný prevod dátumu a vracia názvy mesiacov a dní, ktoré zodpovedajú miestnemu prostrediu VM, na ktorom je spustená naša aplikácia.

Pamätajte: primárnym účelom funkcie rozšírenia je jednoducho umožniť nám prístup k existujúcim funkciám Java; napíš čo najmenej kódu. Funkcia rozšírenia, ako každá metóda Java, môže používať ďalšie metódy v rámci tej istej triedy. Pre zjednodušenie formát () implementáciu som presunul opakujúci sa kód do malej užitočnej metódy:

private void addChild (nadradený uzol, názov reťazca, text reťazca) {Element child = parent.getOwnerDocument (). createElement (name); child.appendChild (parent.getOwnerDocument (). createTextNode (text)); parent.appendChild (dieťa); } 

Použite DateFormatter v šablóne so štýlmi

Teraz, keď sme implementovali funkciu rozšírenia, môžeme ju zavolať zo šablóny štýlov. Rovnako ako predtým, musíme deklarovať menný priestor pre našu funkciu rozšírenia:

Tentokrát sme plne kvalifikovali cestu do triedy, ktorá hostí funkciu rozšírenia. Toto je voliteľné a záleží na tom, či budete používať ďalšie triedy v rámci rovnakého balíka alebo iba jedného rozšíreného objektu. Môžete uviesť celé CLASSPATH ako priestor názvov alebo použite balík a zadajte triedu, kde je vyvolaná funkcia rozšírenia. Upresnením celého CLASSPATH, píšeme menej, keď voláme funkciu.

Ak chcete túto funkciu využiť, jednoducho ju zavolajte z vnútra a vyberte značka, takto:



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