Transformasjon
La oss nå prøve transformasjonen. Utfør følgende kommando:
java XSLTDemo books.xml books.xsl
Dessverre mislykkes denne transformasjonen: du bør observere utdata som identifiserer Apache Xalan som transformatorfabrikk og en feilmelding om at xsl: for hver gruppe
er ikke støttet.
La oss prøve igjen. Antar at saxon9he.jar
og XSLTDemo.class
befinner seg i den gjeldende katalogen, utfører du følgende kommando:
java -cp saxon9he.jar ;. XSLTDemo books.xml books.xsl
Denne gangen bør du observere følgende sorterte og riktig grupperte utdata:
Tillegg til kapittel 11: Behandler JSON med Jackson
Konvertering av XML til JSON med Jackson
Java XML og JSON, kapittel 11, introduserer Jackson, som gir APIer for parsing og oppretting av JSON-objekter. Det er også mulig å bruke Jackson til å konvertere XML-dokumenter til JSON-dokumenter.
I denne delen vil jeg vise deg to måter å konvertere XML til JSON, først med databinding og deretter med treovergang. Jeg antar at du har lest kapittel 11 og er kjent med Jackson. For å følge disse demoene, burde du ha lastet ned følgende JAR-filer fra Maven-arkivet:
jackson-annotations-2.9.7.jar
jackson-core-2.9.7.jar
jackson-databind-2.9.7.jar
Du trenger også noen ekstra JAR-filer; de fleste er felles for begge konverteringsteknikkene. Jeg gir informasjon om hvordan du skaffer deg disse JAR-filene snart.
Konverter XML til JSON med datainnbinding
Databinding lar deg kartlegge serielle data til et Java-objekt. Anta for eksempel at du har et lite XML-dokument som beskriver en enkelt planet. Oppføring 4 presenterer dette dokumentet.
Oppføring 4. planet.xml
Jorden 3 9
Oppføring 5 presenterer en tilsvarende Java Planet
klasse hvis objekter kartlegges til planet.xml
innhold.
Oppføring 5. Planet.java
offentlig klasse Planet {offentlig strengnavn; offentlig Heltall planet_fra sol; offentlige Heltallmåner; }
Konverteringsprosessen krever at du først analyserer XML til en Planet
gjenstand. Du kan utføre denne oppgaven ved å jobbe med com.fasterxml.jackson.dataformat.xml.XmlMapper
klasse, som følger:
XmlMapper xmlMapper = ny XmlMapper (); XMLInputFactory xmlif = XMLInputFactory.newFactory (); FileReader fr = ny FileReader ("planet.xml"); XMLStreamReader xmlsr = xmlif.createXMLStreamReader (fr); Planet planet = xmlMapper.readValue (xmlsr, Planet.class);
XmlMapper
er en tilpasset com.fasterxml.jackson.databind.ObjectMapper
som leser og skriver XML. Det gir flere readValue ()
metoder for å lese en enkelt XML-verdi fra en XML-spesifikk inngangskilde; for eksempel:
T readValue (XMLStreamReader r, Class valueType)
Hver readValue ()
metoden krever en javax.xml.stream.XMLStreamReader
objekt som sitt første argument. Dette objektet er egentlig en StAX-basert strømbasert parser for effektiv parsing av tekst fremover.
Det andre argumentet er en java.lang.Klasse
objekt for måltypen som blir instantiert, fylt med XML-data, og hvis forekomst deretter returneres fra metoden.
Poenget med dette kodefragmentet er at Listing 4s innhold blir lest inn i en Planet
innvende det readValue ()
går tilbake til den som ringer.
Når objektet er opprettet, er det enkelt å skrive det ut som JSON ved å jobbe med ObjectMapper
og dets String writeValueAsString (Objektverdi)
metode:
ObjectMapper jsonMapper = ny ObjectMapper (); String json = jsonMapper.writeValueAsString (planet);
Jeg utdrag disse kodefragmentene fra en XML2JSON
applikasjon hvis komplette kildekode vises i Listing 6.
Oppføring 6. XML2JSON.java (Versjon 1)
importere java.io.FileReader; importere javax.xml.stream.XMLInputFactory; importere javax.xml.stream.XMLStreamReader; importere com.fasterxml.jackson.databind.ObjectMapper; importere com.fasterxml.jackson.dataformat.xml.XmlMapper; importer statisk java.lang.System. *; offentlig klasse XML2JSON {offentlig statisk ugyldig hoved (String [] args) kaster Unntak {XmlMapper xmlMapper = ny XmlMapper (); XMLInputFactory xmlif = XMLInputFactory.newFactory (); FileReader fr = ny FileReader ("planet.xml"); XMLStreamReader xmlsr = xmlif.createXMLStreamReader (fr); Planet planet = xmlMapper.readValue (xmlsr, Planet.class); ObjectMapper jsonMapper = ny ObjectMapper (); String json = jsonMapper.writeValueAsString (planet); out.println (json); }}
Før du kan kompilere liste 5 og 6, må du laste ned Jackson Dataformat XML, som implementeres XMLMapper
. Jeg lastet ned versjon 2.9.7, som samsvarer med versjonene av de andre tre Jackson-pakkene.
Forutsatt at du har lastet ned jackson-dataformat-xml-2.9.7.jar
, utfør følgende kommando (spredt over to linjer for lesbarhet) for å kompilere kildekoden:
javac -cp jackson-core-2.9.7.jar; jackson-databind-2.9.7.jar; jackson-dataformat-xml-2.9.7.jar ;. XML2JSON.java
Før du kan kjøre den resulterende applikasjonen, må du laste ned Jackson Module: JAXB Annotations, og også laste ned StAX 2 API. Jeg lastet ned JAXB Annotations versjon 2.9.7 og StAX 2 API versjon 3.1.3.
Forutsatt at du har lastet ned jackson-module-jaxb-annotations-2.9.7.jar
og stax2-api-3.1.3.jar
, utfør følgende kommando (spredt over tre linjer for lesbarhet) for å kjøre applikasjonen:
java -cp jackson-annotations-2.9.7.jar; jackson-core-2.9.7.jar; jackson-databind-2.9.7.jar; jackson-dataformat-xml-2.9.7.jar; jackson-module-jaxb-annotations-2.9.7.jar; stax2-api-3.1.3.jar ;. XML2JSON
Hvis alt går bra, bør du følge følgende utdata:
{"name": "Earth", "planet_from_sun": 3, "moons": 9}
Konverter XML til JSON med treovergang
En annen måte å konvertere fra XML til JSON er å først analysere XML i et tre med JSON-noder og deretter skrive dette treet til et JSON-dokument. Du kan utføre den første oppgaven ved å ringe en av XMLMapper
er arvet readTree ()
metoder:
XmlMapper xmlMapper = ny XmlMapper (); JsonNode-node = xmlMapper.readTree (xml.getBytes ());
ObjectMapper
s JsonNode readTree (byte [] innhold)
metoden deserialiserer JSON-innhold til et tre av jackson.databind.JsonNode
objekter, og returnerer roten JsonNode
gjenstand for dette treet. I en XmlMapper
kontekst deserialiserer denne metoden XML-innhold i treet. I begge tilfeller overføres JSON- eller XML-innholdet til denne metoden som en rekke byte.
Den andre oppgaven - å konvertere gjenstandstreet til JSON - utføres på en lignende måte som det jeg tidligere viste. Denne gangen er det JsonNode
rotobjekt som sendes til writeValueAsString ()
:
ObjectMapper jsonMapper = ny ObjectMapper (); String json = jsonMapper.writeValueAsString (node);
Jeg utdrag disse kodefragmentene fra en XML2JSON
applikasjon hvis komplette kildekode vises i Listing 7.
Oppføring 7. XML2JSON.java (versjon 2)
importer com.fasterxml.jackson.databind.JsonNode; importere com.fasterxml.jackson.databind.ObjectMapper; importer com.fasterxml.jackson.dataformat.xml.XmlMapper; importer statisk java.lang.System. *; offentlig klasse XML2JSON {offentlig statisk ugyldig hoved (String [] args) kaster Unntak {String xml = "\ n" + "\ n" + "Earth \ n" + "3 \ n" + "1 \ n" + "\ n "; XmlMapper xmlMapper = ny XmlMapper (); JsonNode-node = xmlMapper.readTree (xml.getBytes ()); ObjectMapper jsonMapper = ny ObjectMapper (); String json = jsonMapper.writeValueAsString (node); out.println (json); }}
Utfør følgende kommando (spredt over to linjer for lesbarhet) for å kompilere Listing 7:
javac -cp jackson-core-2.9.7.jar; jackson-databind-2.9.7.jar; jackson-dataformat-xml-2.9.7.jar XML2JSON.java
Før du kan kjøre den resulterende applikasjonen, må du laste ned Woodstox, som er en XML-prosessor med høy ytelse som implementerer StAX, SAX2 og StAX2. Jeg lastet ned Woodstox 5.2.0. Utfør deretter følgende kommando (spredt over tre linjer for lesbarhet) for å kjøre applikasjonen:
java -cp jackson-annotations-2.9.7.jar; jackson-core-2.9.7.jar; jackson-databind-2.9.7.jar; jackson-dataformat-xml-2.9.7.jar; stax2-api-3.1.3.jar; woodstox-core-5.2.0.jar ;. XML2JSON
Hvis alt går bra, bør du følge følgende utdata:
{"name": "Earth", "planet_from_sun": "3", "moons": "1"}
Legg merke til at tallene som er tilordnet planet_fra_sun
og måner
XML-elementer serialiseres til JSON-strenger i stedet for tall. De readTree ()
metoden utleder ikke datatypen i fravær av en eksplisitt typedefinisjon.
Jacksons støtte for XML-trepasning har ytterligere begrensninger:
- Jackson klarer ikke å skille mellom objekter og matriser. Fordi XML ikke gir noen mulighet til å skille et objekt fra en liste (array) av objekter, samler Jackson gjentatte elementer i en enkelt verdi.
- Jackson støtter ikke blandet innhold (tekstlig innhold og elementer som barn av et element). I stedet tilordner det hvert XML-element til en
JsonNode
gjenstand. Enhver tekst går tapt.
Gitt disse begrensningene, er det ikke overraskende at den offisielle Jackson-dokumentasjonen anbefaler å analysere XML i JsonNode
-baserte trær. Du har det bedre å bruke teknologien for konvertering av databinding.
Konklusjon
Materialet som presenteres i denne artikkelen bør betraktes som tillegg til kapittel 6 og 11 i den andre utgaven av Java XML og JSON. Derimot vil min neste artikkel være relatert til boken, men helt nytt materiale. Hold øye med den kommende artikkelen min om å binde Java-objekter til JSON-dokumenter med JSON-B.
Denne historien, "Java XML and JSON: Document processing for Java SE, Part 1: SAXON and Jackson" ble opprinnelig utgitt av JavaWorld.