Java XMLおよびJSON:Java SEのドキュメント処理、パート1:SAXONおよびJackson

前へ12ページ2 2/2ページ

変換

それでは、変換を試してみましょう。次のコマンドを実行します。

java XSLTDemo books.xml books.xsl

残念ながら、この変換は失敗します。ApacheXalanをトランスフォーマーファクトリとして識別する出力と、xsl:for-each-groupサポートされていないことを示すエラーメッセージを確認する必要があります。

もう一度やり直してみましょう。仮定するsaxon9he.jarXSLTDemo.class、現在のディレクトリに配置されていることは、次のコマンドを実行します。

java -cp saxon9he.jar;. XSLTDemo books.xml books.xsl

今回は、次のソートされ、適切にグループ化された出力を確認する必要があります。

第11章の補遺:Jacksonを使用したJSONの処理

Jacksonを使用したXMLからJSONへの変換

Java XMLとJSONの第11章では、JSONオブジェクトを解析および作成するためのAPIを提供するJacksonを紹介しています。Jacksonを使用してXMLドキュメントをJSONドキュメントに変換することもできます。

このセクションでは、XMLをJSONに変換する2つの方法を紹介します。最初はデータバインディングを使用し、次にツリートラバーサルを使用します。あなたは第11章を読み、ジャクソンに精通していると仮定します。これらのデモを実行するには、Mavenリポジトリから次のJARファイルをダウンロードしておく必要があります。

  • jackson-annotations-2.9.7.jar
  • jackson-core-2.9.7.jar
  • jackson-databind-2.9.7.jar

追加のJARファイルもいくつか必要になります。ほとんどは両方の変換手法に共通です。これらのJARファイルの取得に関する情報はまもなく提供します。

データバインディングを使用してXMLをJSONに変換する

データバインディングを使用すると、シリアル化されたデータをJavaオブジェクトにマップできます。たとえば、単一の惑星を説明する小さなXMLドキュメントがあるとします。リスト4にこのドキュメントを示します。

リスト4.planet.xml

  Earth 3 9 

リスト5は、Planetオブジェクトがplanet.xmlのコンテンツにマップされる同等のJavaクラスを示しています。

リスト5.Planet.java

public class Planet { public String name; public Integer planet_from_sun; public Integer moons; }

変換プロセスでは、最初にXMLを解析してPlanetオブジェクトにする必要があります。このタスクcom.fasterxml.jackson.dataformat.xml.XmlMapperは、次のようにクラスを操作することで実行できます。

XmlMapper xmlMapper = new XmlMapper(); XMLInputFactory xmlif = XMLInputFactory.newFactory(); FileReader fr = new FileReader("planet.xml"); XMLStreamReader xmlsr = xmlif.createXMLStreamReader(fr); Planet planet = xmlMapper.readValue(xmlsr, Planet.class);

XmlMappercom.fasterxml.jackson.databind.ObjectMapperXMLを読み書きするカスタマイズされたです。readValue()XML固有の入力ソースから単一のXML値を読み取るためのいくつかの方法を提供します。例えば:

 T readValue(XMLStreamReader r, Class valueType)

readValue()メソッドには、javax.xml.stream.XMLStreamReader最初の引数としてオブジェクトが必要です。このオブジェクトは本質的に、テキストを順方向に効率的に解析するためのStAXベースのストリームベースのパーサーです。

2番目の引数は、java.lang.Classインスタンス化され、XMLデータが入力され、その後そのインスタンスがメソッドから返されるターゲットタイプのオブジェクトです。

このコードフラグメントの要点は、リスト4のコンテンツが、呼び出し元に戻るPlanetオブジェクトに読み込まれることreadValue()です。

オブジェクトが作成されたら、ObjectMapperとそのString writeValueAsString(Object value)メソッドを操作することで、JSONとして簡単に書き出すことができます。

ObjectMapper jsonMapper = new ObjectMapper(); String json = jsonMapper.writeValueAsString(planet);

XML2JSONリスト6に完全なソースコードが表示されているアプリケーションから、これらのコードフラグメントを抜粋しました。

リスト6.XML2JSON.java(バージョン1)

import java.io.FileReader; import javax.xml.stream.XMLInputFactory; import javax.xml.stream.XMLStreamReader; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.dataformat.xml.XmlMapper; import static java.lang.System.*; public class XML2JSON { public static void main(String[] args) throws Exception { XmlMapper xmlMapper = new XmlMapper(); XMLInputFactory xmlif = XMLInputFactory.newFactory(); FileReader fr = new FileReader("planet.xml"); XMLStreamReader xmlsr = xmlif.createXMLStreamReader(fr); Planet planet = xmlMapper.readValue(xmlsr, Planet.class); ObjectMapper jsonMapper = new ObjectMapper(); String json = jsonMapper.writeValueAsString(planet); out.println(json); } }

リスト5と6をコンパイルする前に、を実装するJackson DataformatXMLをダウンロードする必要がありますXMLMapper。他の3つのJacksonパッケージのバージョンと一致するバージョン2.9.7をダウンロードしました。

ダウンロードjackson-dataformat-xml-2.9.7.jarに成功したと仮定して、次のコマンドを実行し(読みやすくするために2行に広げます)、ソースコードをコンパイルします。

javac -cp jackson-core-2.9.7.jar;jackson-databind-2.9.7.jar;jackson-dataformat-xml-2.9.7.jar;. XML2JSON.java

結果のアプリケーションを実行する前に、Jackson Module:JAXB Annotationsをダウンロードし、StAX 2APIもダウンロードする必要があります。JAXBAnnotationsバージョン2.9.7とStAX2APIバージョン3.1.3をダウンロードしました。

あなたが正常にダウンロードしたと仮定するjackson-module-jaxb-annotations-2.9.7.jarstax2-api-3.1.3.jar、アプリケーションを実行するには、次のコマンド(読みやすくするための3つのライン全体での広がり)を実行します。

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

すべてがうまくいけば、次の出力を観察する必要があります。

{"name":"Earth","planet_from_sun":3,"moons":9}

Convert XML to JSON with tree traversal

Another way to convert from XML to JSON is to first parse the XML into a tree of JSON nodes and then write this tree to a JSON document. You can accomplish the first task by calling one of XMLMapper's inherited readTree() methods:

XmlMapper xmlMapper = new XmlMapper(); JsonNode node = xmlMapper.readTree(xml.getBytes());

ObjectMapper's JsonNode readTree(byte[] content) method deserializes JSON content into a tree of jackson.databind.JsonNode objects, and returns the root JsonNode object of this tree. In an XmlMapper context, this method deserializes XML content into the tree. In either case, the JSON or XML content is passed to this method as an array of bytes.

The second task -- converting the tree of objects to JSON -- is accomplished in a similar manner to what I previously showed. This time, it's the JsonNode root object that's passed to writeValueAsString():

ObjectMapper jsonMapper = new ObjectMapper(); String json = jsonMapper.writeValueAsString(node);

I excerpted these code fragments from an XML2JSON application whose complete source code appears in Listing 7.

Listing 7. XML2JSON.java (version 2)

import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.dataformat.xml.XmlMapper; import static java.lang.System.*; public class XML2JSON { public static void main(String[] args) throws Exception { String xml = "\n"+ "\n" + " Earth\n" + " 3\n" + " 1\n" + "\n"; XmlMapper xmlMapper = new XmlMapper(); JsonNode node = xmlMapper.readTree(xml.getBytes()); ObjectMapper jsonMapper = new ObjectMapper(); String json = jsonMapper.writeValueAsString(node); out.println(json); } }

Execute the following command (spread over two lines for readability) to compile 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

Before you can run the resulting application, you'll need to download Woodstox, which is a high-performance XML processor that implements StAX, SAX2, and StAX2. I downloaded Woodstox 5.2.0. Then execute the following command (spread across three lines for readability) to run the application:

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

If all goes well, you should observe the following output:

{"name":"Earth","planet_from_sun":"3","moons":"1"}

Notice that the numbers assigned to the planet_from_sun and moons XML elements are serialized to JSON strings instead of numbers. The readTree() method doesn't infer the data type in the absence of an explicit type definition.

Jackson's support for XML tree traversal has additional limitations:

  • Jackson is unable to differentiate between objects and arrays. Because XML provides no means to differentiate an object from a list (array) of objects, Jackson collates repeated elements into a single value.
  • Jackson doesn't support mixed content (textual content and elements as children of an element). Instead, it maps each XML element to a JsonNode object. Any text is lost.

Given these limitations, it's not surprising that the official Jackson documentation recommends against parsing XML into JsonNode-based trees. You're better off using the data binding conversion technique.

Conclusion

この記事で紹介する資料は、JavaXMLおよびJSONの第2版​​の第6章および第11章の補遺と見なす必要があります。対照的に、私の次の記事は本に関連していますが、まったく新しい資料です。JSON-Bを使用してJavaオブジェクトをJSONドキュメントにバインドすることに関する今後の記事に注目してください。

このストーリー「JavaXMLとJSON:Java SEのドキュメント処理、パート1:SAXONとJackson」は、もともとJavaWorldによって公開されました。