Создать классы Java из файлов .XSD ...? - PullRequest
120 голосов
/ 26 марта 2009

У меня есть гигантский файл схемы QuickBooks SDK .XSD, который определяет запросы / ответы XML, которые я могу отправлять / получать из QuickBooks.

Я хотел бы иметь возможность легко генерировать классы Java из этих файлов .XSD, которые затем я мог бы использовать для упорядочения XML в объекты Java и объектов Java в XML.

Есть ли простой способ сделать это ...?

В идеале для этого не потребуются никакие библиотеки, внешние по отношению к базовому дистрибутиву Java во время выполнения. Но я гибкий ...

Ответы [ 13 ]

118 голосов
/ 26 марта 2009

JAXB делает именно то, что вы хотите. Он встроен в JRE / JDK, начиная с 1.6

116 голосов
/ 30 августа 2011

Чтобы расширить комментарии "use 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

37 голосов
/ 27 марта 2009

Если вы хотите начать кодирование Java в XML и XML в Java менее чем за 5 минут, попробуйте Simple XML Serialization. Не тратьте часы на изучение JAXB API http://simple.sourceforge.net/download/stream/doc/tutorial/tutorial.php

Однако, если вы действительно заинтересованы в изучении JAXB, вот отличный учебник http://blogs.oracle.com/teera/entry/jaxb_for_simple_java_xml

Содержание урока:

JAXB для простой сериализации Java-XML

Существует несколько способов сделать сериализацию XML в Java. Если вам нужен детальный контроль над синтаксическим анализом и сериализацией, вы можете использовать SAX, DOM или Stax для повышения производительности. Тем не менее, я часто хочу сделать простое сопоставление между POJO и XML. Однако создание классов Java для анализа событий XML вручную не является тривиальным. Недавно я обнаружил, что JAXB - это быстрое и удобное отображение или сериализация Java-XML.

JAXB содержит много полезных функций, вы можете проверить справочную реализацию здесь. Блог Kohsuke также является хорошим ресурсом, чтобы узнать больше о JAXB. В этой записи блога я покажу вам, как выполнить простую сериализацию Java-XML с помощью JAXB.

POJO в XML

Допустим, у меня есть объект Item Java. Я хочу сериализовать объект Item в формат XML. Сначала мне нужно аннотировать этот POJO с помощью нескольких аннотаций XML из пакета javax.xml.bind.annotation. *. См. Листинг 1 для Item.java

Из кода

  • @XmlRootElement(name="Item") указывает, что я хочу быть корневым элементом.
  • @XmlType(propOrder = {"name", "price"}) указывает порядок, в котором я хочу, чтобы элемент располагался в выводе XML.
  • @XmlAttribute(name="id", ...) указывает, что id является атрибутом корневого элемента.
  • @XmlElement(....) указывает, что я хочу, чтобы цена и имя были элементом в Item.

Мой Item.java готов. Затем я могу создать скрипт JAXB для маршалинга Item.

//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>

Легко, верно? В качестве альтернативы вы можете направить выходной XML в виде текстовой String, Stream, Writer, ContentHandler и т. Д., Просто изменив параметр метода marshal (...), например

...
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-схемы

Последнее, что я хочу упомянуть, это проверка входного XML со схемой перед демаршаллингом Java-объекту. Я создаю файл схемы XML с именем item.xsd. Полный список кода см. В листинге кода 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.

29 голосов
/ 15 марта 2013

Использование Eclipse IDE: -

  1. скопировать xsd в новый / существующий проект.
  2. Убедитесь, что у вас есть JAXB необходимые JAR в вашем classpath. Вы можете скачать один здесь .
  3. Щелкните правой кнопкой мыши файл XSD -> Создать -> JAXB классы.
16 голосов
/ 12 августа 2016

самый простой способ - использовать командную строку. Просто введите каталог вашего .xsd файла:

xjc myFile.xsd.

Итак, Java будет генерировать все Pojos.

14 голосов
/ 26 марта 2009

XMLBeans сделает это. В частности, команда "scomp".

РЕДАКТИРОВАТЬ: XMLBeans был удален , проверьте этот стековый пост для получения дополнительной информации.

12 голосов
/ 29 апреля 2013

Maven может использоваться для этой цели, вам нужно добавить некоторые зависимости и просто очистить ваше приложение. Вы получите все классы, созданные автоматически в вашей целевой папке.

Просто скопируйте их из целевого в нужное место, вот pom.xml, который я использовал для создания классифицированных из xsd файлов:

    <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

Надеюсь, это поможет:)

7 голосов
/ 13 сентября 2011

Ну, лучший вариант - %java_home%\bin\xjc -p [your namespace] [xsd_file].xsd.

У меня также есть вопрос, есть ли у нас возможность сделать обратный инжиниринг здесь. если да, можем ли мы сгенерировать xsd из класса pojo?

7 голосов
/ 26 марта 2009

Если вы не возражаете против использования внешней библиотеки, я использовал Castor для этого в прошлом.

5 голосов
/ 27 апреля 2010

JAXB ограничение.

Я работал над JAXB, по моему мнению, это хороший способ работы с данными между объектами XML и Java. Положительными сторонами являются его проверенная и лучшая производительность и контроль данных во время выполнения. При хорошем использовании встроенных инструментов или сценариев это отнимает много усилий при написании кода.

Я обнаружил, что настройка не является простой задачей, и потратил часы на настройку среды разработки.

Однако я отказался от этого решения из-за глупого ограничения, с которым я столкнулся. У моего определения схемы XML (XSD) есть атрибут / элемент с именем «value», и я должен использовать XSD как есть. Это очень небольшое ограничение привело к сбою шага привязки my XJC с ошибкой «Свойство« Значение »уже используется».

Это связано с реализацией JAXB, процесс привязки пытается создать объекты Java из XSD, добавляя несколько атрибутов к каждому классу, один из которых является атрибутом значения. Когда он обработал мой XSD, он пожаловался, что уже существует свойство с таким именем.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...