Java XML 및 JSON : Java SE 용 문서 처리, Part 1 : SAXON 및 Jackson

이전 1 2 페이지 2 페이지 2/2

변환

이제 변형을 시도해 봅시다. 다음 명령을 실행하십시오.

java XSLTDemo books.xml books.xsl

불행히도이 변환은 실패합니다. Apache Xalan을 변환기 팩토리로 식별하는 출력과 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으로 변환하는 두 가지 방법을 보여줍니다. 나는 당신이 11 장을 읽었고 Jackson에 익숙하다고 가정 할 것이다. 이 데모를 따르려면 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 문서가 있다고 가정합니다. Listing 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 기반 스트림 기반 파서입니다.

두 번째 인수는 java.lang.Class인스턴스화되고 XML 데이터로 채워지며 이후에 메서드에서 해당 인스턴스가 반환되는 대상 유형에 대한 개체입니다.

이 코드 조각의 요점은 Listing 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); } }

Listings 5와 6을 컴파일하기 전에 .NET Framework를 구현하는 Jackson Dataformat XML을 다운로드해야합니다 XMLMapper. 다른 세 개의 Jackson 패키지 버전과 일치하는 버전 2.9.7을 다운로드했습니다.

을 성공적으로 다운로드했다고 가정 jackson-dataformat-xml-2.9.7.jar하고 다음 명령 (가독성을 위해 두 줄에 걸쳐)을 실행하여 소스 코드를 컴파일합니다.

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 2 API도 다운로드해야합니다. JAXB Annotations 버전 2.9.7 및 StAX 2 API 버전 3.1.3을 다운로드했습니다.

성공적으로 다운로드 한 것을 가정 jackson-module-jaxb-annotations-2.9.7.jar하고 stax2-api-3.1.3.jar응용 프로그램을 실행하기 위해 다음 명령 (읽기 쉽도록 세 줄에 걸쳐 확산)을 실행합니다 :

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

이 기사에 제시된 자료는 Java XML 및 JSON 제 2 판 6 장과 11 장의 부록으로 간주되어야합니다 . 대조적으로, 나의 다음 기사는 책과 관련이 있지만 완전히 새로운 자료입니다. JSON-B를 사용하여 Java 개체를 JSON 문서에 바인딩하는 방법에 대한 향후 기사를 주시하십시오.

이 스토리 "Java XML 및 JSON : Java SE 용 문서 처리, Part 1 : SAXON 및 Jackson"은 원래 JavaWorld에서 게시했습니다.