.XSD 파일에서 Java 클래스 생성…?


127

QuickBooks에서 보내거나받을 수있는 XML 요청 / 응답을 정의하는 거대한 QuickBooks SDK .XSD 스키마 파일이 있습니다.

이 .XSD 파일에서 Java 클래스를 쉽게 생성 할 수 있기를 원합니다. 그런 다음 XML을 Java 객체로, Java 객체를 XML로 마샬링하는 데 사용할 수 있습니다.

이 작업을 수행하는 쉬운 방법이 있습니까?

이상적으로는 런타임시 기본 Java 배포 외부에 라이브러리가 필요하지 않습니다. 그러나 나는 유연합니다 ...


6
수동 생성을 원한다면 이클립스 프로젝트에 .xsd 파일을 넣고 파일을 마우스 오른쪽 버튼으로 클릭 한 다음 "generate"
Junchen Liu

답변:


121

JAXB 는 원하는 것을 정확하게 수행합니다. 1.6부터 JRE / JDK에 내장


7
불행히도이 기능은 Java 9부터 더 이상 사용할 수 없습니다. 관련 클래스 (특히 com.sun.tools.xjc. * 클래스)를 더 이상 JDK를 통해 사용할 수 없기 때문입니다.
Marco

4
java.net 프로젝트 (답변에 링크되어 있음)가 계속 유지 될 것이기 때문에 JDK에서 이것을 제거하는 것이 문제가 될 것이라고 생각하지 않습니다.
stmoebius

1
여기설명 된 대로 명령 행 인수로 Java 9의 종속성을 추가하거나 종속성을 수동으로 추가 할 수 있습니다.
Matthias Ronge

118

위의 "JAXB 사용"주석을 확장하려면

Windows에서 "%java_home%\bin\xjc" -p [your namespace] [xsd_file].xsd

예를 들어 "%java_home%\bin\xjc" -p com.mycompany.quickbooks.obj quickbooks.xsd

조금만 기다리십시오. 잘 구성된 XSD 파일이 있으면 잘 구성된 Java 클래스를 얻게됩니다.


3
감사합니다! 캡슐화되지 않고 최상위 클래스를 생성하려면 stackoverflow.com/questions/13175224/…를 참조하십시오 . 클래스 이름 충돌로 이어질 경우 다음을 참조하십시오. stackoverflow.com/questions/13414407/…
내일

38

5 분 이내에 Java에서 XML로, XML에서 Java로 코딩을 시작하려면 단순 XML 직렬화를 시도하십시오. JAXB API를 배우는 데 시간을 소비하지 마십시오 http://simple.sourceforge.net/download/stream/doc/tutorial/tutorial.php

그러나 JAXB를 배우는 데 관심이 있다면 훌륭한 자습서가 있습니다. http://blogs.oracle.com/teera/entry/jaxb_for_simple_java_xml

튜토리얼의 내용 :

간단한 Java-XML 직렬화를위한 JAXB

Java에서 XML 직렬화를 수행하는 여러 가지 방법이 있습니다. 구문 분석 및 직렬화를 세밀하게 제어하려면 SAX, DOM 또는 Stax를 사용하여 성능을 향상시킬 수 있습니다. 그러나 내가 자주하고 싶은 일은 POJO와 XML 간의 간단한 매핑입니다. 그러나 수동으로 XML 이벤트 구문 분석을 수행하기 위해 Java 클래스를 작성하는 것은 쉽지 않습니다. 최근에 JAXB가 빠르고 편리한 Java-XML 매핑 또는 직렬화라는 것을 알았습니다.

JAXB에는 유용한 기능이 많이 있으며 여기에서 참조 구현을 확인할 수 있습니다. Kohsuke의 블로그 는 JAXB에 대해 더 자세히 배울 수있는 좋은 자료입니다. 이 블로그 항목에서는 JAXB를 사용하여 간단한 Java-XML 직렬화를 수행하는 방법을 보여줍니다.

POJO에서 XML로

Item Java 객체가 있다고 가정 해 봅시다. Item 객체를 XML 형식으로 직렬화하고 싶습니다. 먼저해야 할 일은 javax.xml.bind.annotation. * 패키지의 XML 주석으로이 POJO에 주석을 달아야합니다. Item.java에 대한 코드 목록 1을 참조하십시오.

코드에서

  • @XmlRootElement(name="Item") 내가 루트 요소가되고 싶다는 것을 나타냅니다.
  • @XmlType(propOrder = {"name", "price"}) 요소를 XML 출력으로 정렬하려는 순서를 나타냅니다.
  • @XmlAttribute(name="id", ...) id가 루트 요소의 속성임을 나타냅니다.
  • @XmlElement(....) 가격과 이름이 Item의 요소가 되길 원한다는 것을 나타냅니다.

Item.java준비가되었습니다. 그런 다음 Item 마샬링을위한 JAXB 스크립트를 작성할 수 있습니다.

//creating Item data object
Item item = new Item();
item.setId(2);
item.setName("Foo");
item.setPrice(200);
.....

JAXBContext context = JAXBContext.newInstance(item.getClass());
Marshaller marshaller = context.createMarshaller();
//I want to save the output file to item.xml
marshaller.marshal(item, new FileWriter("item.xml"));

전체 코드 목록은 코드 목록 2를 참조하십시오 main.java. 출력 코드 목록 3 item.xml파일이 작성됩니다. 다음과 같이 보입니다 :

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ns1:item ns1:id="2" xmlns:ns1="http://blogs.sun.com/teera/ns/item">

 <ns1:itemName>Foo</ns1:itemName>
<ns1:price>200</ns1:price>

</ns1:item>

쉬운가요? 또는 단순히 marshal (...) 메소드의 매개 변수를 변경하여 출력 XML을 텍스트 문자열, 스트림, 작성기, ContentHandler 등으로 채널링 할 수 있습니다.

...
JAXBContext context = JAXBContext.newInstance(item.getClass());
Marshaller marshaller = context.createMarshaller();
// save xml output to the OutputStream instance
marshaller.marshal(item, <java.io.OutputStream instance>);

...
JAXBContext context = JAXBContext.newInstance(item.getClass());
Marshaller marshaller = context.createMarshaller();
StringWriter sw = new StringWriter();
//save to StringWriter, you can then call sw.toString() to get java.lang.String
marshaller.marshal(item, sw);

XML에서 POJO로

과정을 반대로하자. 이제 XML 문자열 데이터 조각이 있고이를 Item.java 객체로 변환하려고한다고 가정합니다. XML 데이터 (코드 목록 3)는 다음과 같습니다.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ns1:item ns1:id="2" xmlns:ns1="http://blogs.sun.com/teera/ns/item">
<ns1:itemName>Bar</ns1:itemName>
<ns1:price>80</ns1:price>
</ns1:item>

그런 다음이 XML 코드를 Item 객체에 정렬 해제 할 수 있습니다

...
ByteArrayInputStream xmlContentBytes = new ByteArrayInputStream (xmlContent.getBytes());
JAXBContext context = JAXBContext.newInstance(Item.getClass());
Unmarshaller unmarshaller = context.createUnmarshaller();
//note: setting schema to null will turn validator off
unmarshaller.setSchema(null);
Object xmlObject = Item.getClass().cast(unmarshaller.unmarshal(xmlContentBytes));
return xmlObject;
...

전체 코드 목록은 코드 목록 2 (main.java)를 참조하십시오. XML 소스는 스트림과 파일 모두에서 여러 형태로 제공 될 수 있습니다. 유일한 차이점은 메소드 매개 변수입니다.

...
unmarshaller.unmarshal(new File("Item.xml")); // reading from file
...
// inputStream is an instance of java.io.InputStream, reading from stream
unmarshaller.unmarshal(inputStream);

XML 스키마를 사용한 유효성 검사

마지막으로 언급하고자하는 것은 Java 객체를 비 정렬 화하기 전에 스키마로 입력 XML의 유효성을 검사하는 것입니다. item.xsd라는 XML 스키마 파일을 만듭니다. 전체 코드 목록은 코드 목록 4 (Item.xsd)를 참조하십시오. 이제 내가해야 할 일은 유효성 검사를 위해이 스키마를 등록하는 것입니다.

...
Schema schema = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI)
.newSchema(new File("Item.xsd"));
unmarshaller.setSchema(schema); //register item.xsd shcema for validation
...

XML 데이터를 POJO로 비 정렬 화하려고 할 때 입력 XML이 스키마를 준수하지 않으면 예외가 발생합니다. 전체 코드 목록은 코드 목록 5 (invalid_item.xml)를 참조하십시오.

javax.xml.bind.UnmarshalException
- with linked exception:
javax.xml.bind.JAXBException caught: null
[org.xml.sax.SAXParseException: cvc-datatype-valid.1.2.1: 'item1' is
                                not a valid value for 'integer'.]

여기서는 'id'속성을 정수 대신 문자열로 변경합니다.

XML 입력이 스키마에 대해 유효한 경우 XML 데이터는 Item.java 오브젝트에 성공적으로 비 정렬 화됩니다.


1
이것은 매우 유망하고 JAXB와 같이 크고 복잡한 것보다 내가 필요한 것에 대해 작업하는 것이 훨씬 간단하고 멋지게 보입니다. 불행히도 기존 .XSD를 .class 파일로 변환 할 수있는 방법이 없습니다. 실제로 시작해야합니다. 이것을 할 수있는 방법이 있습니까?
Keith Palmer Jr.

7
불행히도 JAXB Tutorial이있는 블로그는 오프라인 상태입니다.
Luis C.

jaxb2-maven-plugin을 사용하여 쉽게 할 수 있습니다.이 튜토리얼을 확인하십시오 journaldev.com/1312/…
Pankaj

""% java_home % \ bin \ xjc "-p [네임 스페이스] [xsd_file] .xsd"에 대해 무엇이 복잡합니까?
gorefest

30

Eclipse IDE 사용 :-

  1. xsd를 새로운 기존 프로젝트에 복사하십시오.
  2. 클래스 경로에 JAXB 필수 JAR이 있는지 확인하십시오. 여기에서 다운로드 할 수 있습니다 .
  3. XSD 파일-> 생성-> JAXB 클래스를 마우스 오른쪽 단추로 클릭하십시오.

17

가장 쉬운 방법은 명령 줄을 사용하는 것입니다. .xsd 파일의 디렉토리를 입력하십시오.

xjc myFile.xsd.

따라서 java는 모든 Pojo를 생성합니다.


14

Maven을 목적으로 사용할 수 있으므로 일부 종속성을 추가하고 응용 프로그램을 정리해야합니다. 대상 폴더에 모든 클래스가 자동으로 생성됩니다.

대상에서 원하는 위치로 복사하십시오 .xsd 파일에서 클래스를 만드는 데 사용한 pom.xml이 있습니다.

    <plugin>
     <groupId>org.codehaus.mojo</groupId>
     <artifactId>jaxb2-maven-plugin</artifactId>

     <executions>
      <execution>
       <goals>
        <goal>xjc</goal>
       </goals>
      </execution>
     </executions>
     <configuration>
      <schemaDirectory>src/main/webapp/schemas/</schemaDirectory>
     </configuration>
    </plugin>

   </plugins>
  </pluginManagement>
 </build>
</project>

xsd 파일을 "src / main / webapp / schemas /"아래에 놓으면 maven이 컴파일시에 찾을 수 있습니다.

이것이 도움이되기를 바랍니다. 더 자세한 정보는 http://www.beingjavaguys.com/2013/04/create-spring-web-services-using-maven.html 에서 찾을 수 있습니다

그것이 도움이되기를 바랍니다 :)


1
이것은 실제로 resources 디렉토리와 함께 작동합니까? (SRC / 메인 / 자원 / 스키마),이 점점 계속 때문에 :No XSD files found. Please check your plugin configuration.
zygimantus


7

가장 좋은 옵션은 %java_home%\bin\xjc -p [your namespace] [xsd_file].xsd입니다.

여기에서 리버스 엔지니어링을 수행 할 수있는 옵션이 있는지 궁금합니다. 그렇다면 pojo 클래스에서 xsd를 생성 할 수 있습니까?


xjc는 java6에서만 사용 가능
sree

7

외부 라이브러리를 사용하는 것이 마음에 들지 않으면 과거에 Castor 를 사용 하여이 작업을 수행했습니다.


Castor로 코드를 생성하는 경우 생성 된 클래스가 사실 후에도 Caster에 종속됩니까? 아니면 이러한 클래스를 Castor 라이브러리가없는 머신으로 옮길 수 있습니까? 그래도 작동합니까?
Keith Palmer Jr.

아니오, 생성 된 클래스는 Castor 라이브러리에 종속되지 않습니다.
dave

Castor를 사용하여이를 수행하는 방법에 대한 유용한 자습서가 있습니까? 매우 유망한 것처럼 보이지만 Java는 가장 강한 언어는 아닙니다. 다운로드해야하는 Castor 파일 / 패키지 및 실제로 코드 생성 방법을 잘 모르겠습니다. 단계별 초보자 사례는 무엇입니까?
Keith Palmer Jr.

Castor SourceGenerator 클래스를 사용하는 방법에 대한 설명서는이 페이지를 참조하십시오. castor.org/sourcegen.html
Marc Novakowski

2
캐스터가 오랫동안 죽었던 것 같습니다 ... 문서 링크가 모두 404입니다.
Pawel Veselov

5

JAXB 제한 사항.

내 의견에 따르면 JAXB에서 XML과 Java 객체 간의 데이터를 처리하는 좋은 방법으로 작업했습니다. 긍정적 인 측면은 성능 및 성능면에서 런타임 동안 데이터에 대한 검증되고 우수합니다. 빌드 된 도구 나 스크립트를 잘 사용하면 많은 코딩 노력이 필요합니다.

구성 부분이 직접적인 작업이 아니며 개발 환경 설정에 몇 시간이 걸렸습니다.

그러나 나는 직면 한 어리석은 한계로 인해이 솔루션을 삭제했습니다. 내 XML 스키마 정의 (XSD)에는 이름이 "value"인 속성 / 요소가 있으며 XSD를 그대로 사용해야합니다. 이 제한 조건으로 인해 바인딩 단계 XJC가 "속성 '값'이 이미 사용되었습니다"라는 오류와 함께 실패했습니다.

이것은 JAXB 구현으로 인해, 바인딩 프로세스는 각 클래스에 속성 몇 개를 추가하고 값 속성 인 속성 중 하나를 추가하여 XSD에서 Java 오브젝트를 작성하려고합니다. XSD를 처리 할 때 이미 해당 이름의 속성이 있다고 불평했습니다.


4

JAXB의 XJC가 이것에 대한 가능한 대답이 아닙니까? 나는 같은 것을 성취하려고합니다. 그래도 "시도"단계에 있습니다. XJC를 건너 왔으므로 공유를 생각했습니다.



당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.