Java és az XML

Felhasznált technológiák: Java 7, JUnit 4.11, XmlUnit 1.5, Hamcrest 1.3, xml-matchers 1.0-RC1, Maven 3.0.3

Van pár régebbi anyagom, melyet szeretnék publikálni, mielőtt új témákba kezdenék bele. Ebből egyik a Java XML kezeléséről szól, ami ugyan nem a legforróbb terület manapság, azonban mégsem árthat egy kis összefoglaló.

Ehhez poszthoz is található egy projekt a GitHub-on, melyben rengeteg példa van.

Maga a Java SE is meglehetősen komplex XML támogatást tartalmaz, méghozzá a The Java™ API For XML Processing (JAXP), The Java Architecture For XML Binding (JAXB) és The Java API for XML Web Services (JAX-WS) specifikációk formájában. Az JAXP egyszerű alap XML feldolgozást támogat, ide tartozik pl. a SAX, DOM, validáció, XPath, transzformáció, stb. A JAXB egy binding megoldás, mellyel Java objektumokat tudunk XML dokumentumohoz rendelni. És végül a JAX-WS, mellyel webszolgáltatásokat tudunk hívni, és implementálni.

Természetesen a JAXP maga is egy specifikáció, JSR-206. Itt az is látható, hogy melyik Java verzióban ennek melyik verziója szerepel:

  • JAXP 1.6: Java Platform, Standard Edition 8
  • JAXP 1.5: Java Platform, Standard Edition 7u40
  • JAXP 1.4.5: Java Platform, Standard Edition 7
  • JAXP 1.4: Java Platform, Standard Edition 6
  • JAXP 1.3: Java Platform, Standard Edition 5

Az 1.4-es újdonsága a Streaming API for XML (StAX), míg az 1.5 bizonyos biztonsági funkciókkal egészítette ki az előző verziót. A JAXP 1.5 2013 augusztus 30-án jött ki, és a következő szabványokat támogatja:

  • SAX 2.0.2
  • StAX 1.2, JSR 173
  • XML 1.0, XML 1.1
  • XInclude 1.0
  • DOM Level 3 Core, DOM Level 3 Load and Save
  • W3C XML Schema 1.0
  • XSLT 1.0
  • XPath 1.0

A JAXP-hez is tartozik referencia implementáció, mely frappánsan a JAXP reference implementation nevet kapta. Alapvetően két Apache-s projekttől forkolt el, az egyikt az XML parse-olást végző Xerces2, a másik az XML transzformációt végző Xalan-Java.

Gyakorlatilag annyi történt, hogy a csomag neve elé még betették a com.sun.org előtagot. Bármikor megtudhatjuk, hogy az aktuális JDK-ban hanyas Xerces és Xalan található:

System.out.println(com.sun.org.apache.xerces.internal.impl.Version
    .getVersion());
System.out.println(com.sun.org.apache.xalan.internal.Version
    .getVersion());

Ez nekem a JDK 1.7.0_51 esetén a következőt írja ki:

Xerces-J 2.7.1
Xalan Java 2.7.0

A cikk írásának pillanatában mindkettőből van frissebb verzió, a Xerces-ből 2.11.0, a Xalan-ból a 2.7.1.

Mivel a JAXP csak egy API, könnyen lehet az implementációt is cserélni alatta. Ennek mikéntje a Java API DocumentBuilderFactory osztályánál van leírva.

Ha nem tudjuk, hogy éppen melyik verziót használjuk (mert pl. a classpath-on szerepel egy más implementáció, ami alkalmazásszerverek használata esetén is gyakori), akkor a következőképpen állapíthatjuk meg azt:

System.out.println(getJaxpImplementationInfo("DocumentBuilderFactory", 
    DocumentBuilderFactory.newInstance().getClass()));
System.out.println(getJaxpImplementationInfo("XPathFactory", 
    XPathFactory.newInstance().getClass()));
System.out.println(getJaxpImplementationInfo("TransformerFactory", 
    TransformerFactory.newInstance().getClass()));
System.out.println(getJaxpImplementationInfo("SAXParserFactory",
    SAXParserFactory.newInstance().getClass()));

Ez amúgy a példaprojektben is kijött, ugyanis az xml-matchers berántotta a Xerces újabb, 2.8.0 verzióját, ami az egyik XML-t más formátumban írta ki (az mvn dependency:tree paranccsal ellenőrizhető).

A JAXP-hez remek tutorial is található az Oracle oldalán.

A JAXP-ben három parser található. A Simple API for XML (SAX), Document Object Model (DOM) és a Streaming API for XML (StAX). A SAX (mely egy de facto szabvány) egy push parser, a DOM (mely egy W3C szabvány) memóriában felépíti a teljes fát és a StAX pedig egy pull parser, és önmagán belül is még két lehetőséget tartalmaz parse-olásra. Mindegyikre található példa a példa alkalmazásban, és a StAX-ról régebben egy posztot is írtam.

A TransformerFactory és Transformer osztályok használatával lehet XML transzformációkat végezni.

XML séma alapján validálni a Validator osztállyal lehetséges, a Schema betöltése SchemaFactory-val történik. DTD alapján nem tud validálni, ha mégis ilyent szeretnénk, akkor a parsernél kell a validációt beállítani.

A JAXP XPath kiértékelési lehetőségeit a XPathFactory osztályon és XPath interfészen keresztül lehet kihasználni.

A JAXP minden része fel van szerelve névterek kezelésére is.

Az XML funkciók unit tesztelésére több könyvtár is rendelkezésünkre áll (mindegyikre található példa a példa projektben). Az XMLUnit alkalmas XML összehasonlításra (nem szöveg összehasonlítás), XPath kifejezések futtatására, validációra és transzformációk ellenőrzésére. A Hamcrest is tartalmaz egy HasXPath osztályt, azonban ha komolyabb dolgokra van szükségünk, javasolt az xml-matchers használata, ami szintén Hamcrest matchereket tartalmaz.

Az XML kezeléshez tartozó következő API a JAXB, melyről már írtam a JAXB és JAXB trükkök cikkben.

A JAX-WS-ről írtam a JAX-WS mélyvíz posztban, tesztelésükről a Webszolgáltatások integrációs tesztelése soapUI és JUnit használatával posztban. Könyvről a SOA Using Java Web Services posztban, és vizsgáról a Oracle Certified Expert, Java EE 6 Web Services Developer posztban.

Az XML-lel kapcsolatban még érdemes megjegyezni, hogy a properties állományokat is lehet XML formában tárolni, ekkor a Properties osztály loadFromXML metódusát kell meghívni.

Nagyon egyszerű esetben, amennyiben JavaBean-eket akarunk kiírni, majd visszaolvasni, és nem számít az XML felépítése, használhatjuk a Java XMLEncoder és XMLDecoder osztályát.

A javax.xml.soap csomag felelős a SOAP üzenetek alacsony szintű feldolgozásáért.

A két legelterjedtebb nyílt forráskódú XML feldolgozást végző XML library a JDOM és dom4j. Alternatív binding könyvtár a Castor. Alternatív JAXB implementáció az EclipseLink MOXy.

A témával kapcsolatban két könyvet ajánlok. Az egyik a Brett McLaughlin, Justin Edelson: Java and XML, a másik a
Ajay Vohra: Pro XML Development with Java Technology Paperback.