Java XML dan JSON: Pemrosesan dokumen untuk Java SE, Bagian 1: SAXON dan Jackson

Sebelumnya 1 2 Halaman 2 Halaman 2 dari 2

Transformasi

Sekarang mari kita coba transformasi. Jalankan perintah berikut:

java XSLTDemo books.xml books.xsl

Sayangnya, transformasi ini gagal: Anda harus mengamati keluaran yang mengidentifikasi Apache Xalan sebagai pabrik transformator dan pesan kesalahan yang menyatakan bahwa xsl:for-each-grouptidak didukung.

Mari coba lagi. Dengan asumsi itu saxon9he.jardan XSLTDemo.classterletak di direktori saat ini, jalankan perintah berikut:

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

Kali ini, Anda harus mengamati keluaran yang diurutkan dan dikelompokkan dengan benar berikut ini:

Tambahan Bab 11: Memproses JSON dengan Jackson

Mengonversi XML ke JSON dengan Jackson

Java XML dan JSON, Bab 11, memperkenalkan Jackson, yang menyediakan API untuk mengurai dan membuat objek JSON. Mungkin juga menggunakan Jackson untuk mengonversi dokumen XML ke dokumen JSON.

Di bagian ini, saya akan menunjukkan dua cara untuk mengonversi XML ke JSON, pertama dengan data binding dan kemudian dengan tree traversal. Saya akan berasumsi bahwa Anda telah membaca Bab 11 dan akrab dengan Jackson. Untuk mengikuti demo ini, Anda harus mendownload file JAR berikut dari repositori Maven:

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

Anda juga memerlukan beberapa file JAR tambahan; paling umum untuk kedua teknik konversi. Saya akan memberikan informasi tentang cara mendapatkan file JAR ini segera.

Konversikan XML ke JSON dengan pengikatan data

Data binding memungkinkan Anda memetakan data serial ke objek Java. Misalnya, Anda memiliki dokumen XML kecil yang mendeskripsikan satu planet. Kode 4 menyajikan dokumen ini.

Daftar 4. planet.xml

  Earth 3 9 

Kode 5 menyajikan Planetkelas Java yang setara yang objeknya dipetakan ke planet.xmlkonten.

Daftar 5. Planet.java

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

Proses konversi mengharuskan Anda mengurai XML menjadi Planetobjek terlebih dahulu. Anda dapat menyelesaikan tugas ini dengan bekerja bersama com.fasterxml.jackson.dataformat.xml.XmlMapperkelas, sebagai berikut:

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);

XmlMapperadalah kustomisasi com.fasterxml.jackson.databind.ObjectMapperyang membaca dan menulis XML. Ini menyediakan beberapa readValue()metode untuk membaca nilai XML tunggal dari sumber input khusus XML; sebagai contoh:

 T readValue(XMLStreamReader r, Class valueType)

Setiap readValue()metode membutuhkan javax.xml.stream.XMLStreamReaderobjek sebagai argumen pertamanya. Objek ini pada dasarnya adalah parser berbasis aliran berbasis StAX untuk mengurai teks secara efisien dengan cara yang maju.

Argumen kedua adalah java.lang.Classobjek untuk tipe target yang dibuat instance-nya, diisi dengan data XML, dan yang instance-nya kemudian dikembalikan dari metode.

Intinya dari potongan kode ini adalah bahwa konten Listing 4 dibaca menjadi Planetobjek yang readValue()kembali ke pemanggilnya.

Setelah objek dibuat, mudah untuk menuliskannya sebagai JSON dengan menggunakan ObjectMapperdan String writeValueAsString(Object value)metodenya:

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

Saya mengutip potongan-potongan kode ini dari XML2JSONaplikasi yang kode sumber lengkapnya muncul di Daftar 6.

Listing 6. XML2JSON.java (Versi 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); } }

Sebelum Anda dapat mengompilasi Listing 5 dan 6, Anda perlu mengunduh Jackson Dataformat XML yang akan diimplementasikan XMLMapper. Saya mengunduh versi 2.9.7, yang cocok dengan versi dari tiga paket Jackson lainnya.

Dengan asumsi Anda telah berhasil mengunduh jackson-dataformat-xml-2.9.7.jar, jalankan perintah berikut (tersebar di dua baris agar terbaca) untuk mengompilasi kode sumber:

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

Sebelum Anda dapat menjalankan aplikasi yang dihasilkan, Anda harus mengunduh Jackson Module: JAXB Annotations, dan juga mengunduh StAX 2 API. Saya mendownload JAXB Annotations versi 2.9.7 dan StAX 2 API versi 3.1.3.

Dengan asumsi Anda telah berhasil mengunduh jackson-module-jaxb-annotations-2.9.7.jardan stax2-api-3.1.3.jar, jalankan perintah berikut (tersebar di tiga baris agar terbaca) untuk menjalankan aplikasi:

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

Jika semuanya berjalan dengan baik, Anda harus memperhatikan output berikut:

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

Konversi XML ke JSON dengan traversal pohon

Cara lain untuk mengonversi dari XML ke JSON adalah dengan mengurai XML menjadi pohon node JSON terlebih dahulu, lalu menulis pohon ini ke dokumen JSON. Anda dapat menyelesaikan tugas pertama dengan memanggil salah satu metode yang XMLMapperdiwariskan readTree():

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

ObjectMapper's JsonNode readTree(byte[] content)metode deserializes konten JSON menjadi pohon jackson.databind.JsonNodebenda, dan kembali akar JsonNodeobjek pohon ini. Dalam XmlMapperkonteksnya, metode ini memisahkan konten XML ke dalam pohon. Dalam kedua kasus tersebut, konten JSON atau XML diteruskan ke metode ini sebagai larik byte.

Tugas kedua - mengubah pohon objek menjadi JSON - dilakukan dengan cara yang mirip dengan yang saya tunjukkan sebelumnya. Kali ini, JsonNodeobjek root yang diteruskan ke 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

Materi yang disajikan dalam artikel ini harus dianggap sebagai tambahan untuk Bab 6 dan 11 di Java XML dan JSON edisi kedua . Sebaliknya, artikel saya berikutnya akan berhubungan dengan buku itu tetapi materi yang sama sekali baru. Nantikan artikel saya yang akan datang tentang mengikat objek Java ke dokumen JSON dengan JSON-B.

Cerita ini, "Java XML dan JSON: Pemrosesan dokumen untuk Java SE, Bagian 1: SAXON dan Jackson" pada awalnya diterbitkan oleh JavaWorld.