Генерация классов Java из файлов .XSD…?

119

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

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

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

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

  • 6
    Если вы хотите ручную генерацию, поместите файл .xsd в ваш проект eclipse, щелкните правой кнопкой мыши по файлу и нажмите «генерировать»
Теги:
xsd

13 ответов

117
Лучший ответ

JAXB делает ТОЧНО, что вы хотите. Он встроен в JRE/JDK, начиная с 1,6

  • 7
    К сожалению, эта функциональность больше не будет доступна с Java 9. Это связано с тем, что задействованные классы (в частности, классы com.sun.tools.xjc. *) Больше не будут доступны через JDK.
  • 2
    Я не думаю, что удаление этого из JDK должно быть проблемой, потому что проект java.net (ссылка в ответе), вероятно, останется.
Показать ещё 1 комментарий
113

Чтобы развернуть комментарии "Использовать 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

36

Если вы хотите начать кодирование Java в XML и XML на Java менее чем за 5 минут, попробуйте выполнить Simple XML Serialization. Не тратьте время на изучение API JAXB 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

Скажем, у меня есть объект Java 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.java готов. Затем я могу продолжить и создать JAXB script для маршалинга 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 и т.д., Просто изменив параметр метода маршала (...), например

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

  • 1
    Это выглядит очень многообещающе, и гораздо проще и приятнее работать для того, для чего мне это нужно, чем для чего-то большого и сложного, такого как JAXB. К сожалению, я не вижу способа конвертировать мои существующие файлы .XSD в файлы .class, и это действительно то, что мне нужно для начала. Есть ли способ сделать это?
  • 7
    К сожалению, блог с JAXB Tutorial находится в автономном режиме.
Показать ещё 2 комментария
27

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

  • скопируйте xsd в новый/существующий проект.
  • Убедитесь, что JAXB требует JAR в вашем классе. Вы можете скачать здесь.
  • Щелкните правой кнопкой мыши на файле XSD → Generate → JAXB.
14

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

EDIT: XMLBeans был удален в отставку, отметьте https://stackoverflow.com/questions/27727546/what-to-use-instead-of-xmlbeans-now-that-it-has-been-retired для более Информация.

  • 2
    Да, но XMLBeans был прекращен.
  • 0
    stackoverflow.com/questions/27727546/...
Показать ещё 1 комментарий
12

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

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

  • 0
    Это на самом деле работает с каталогом ресурсов? (src / main / resources / schemas), потому что я продолжаю получать следующее: No XSD files found. Please check your plugin configuration.
11

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

xjc myFile.xsd.

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

7

Наилучшим вариантом является %java_home%\bin\xjc -p [your namespace] [xsd_file].xsd.

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

  • 0
    xjc доступен только в java6
7

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

  • 0
    Если вы генерируете код с помощью Castor, эти сгенерированные классы по-прежнему зависят от Caster? Или я могу переместить эти классы на компьютер без библиотек Castor, и они все еще будут работать?
  • 0
    Нет, сгенерированные классы не зависят от библиотек Castor.
Показать ещё 5 комментариев
5

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

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

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

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

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

4

Является ли JAXB XJC возможным ответом на это? Я пытаюсь добиться того же. Тем не менее, в фазе "попытки". Пришел через XJC, поэтому подумал о совместном использовании.

2

Известный JAXB

Существует maven plugin, который может сделать это для вас на любой фазе сборки, которую вы хотите.

Вы можете сделать это в обоих направлениях: xsd ↔ Java

1

Говоря о ограничении JAXB, решение, имея одно и то же имя для разных атрибутов, добавляет встроенные jaxb-настройки в xsd:

+

      ,     ,     обязательные объявления     ,     ,  

или внешние настройки...

Вы можете узнать дополнительную информацию о: http://jaxb.java.net/tutorial/section_5_3-Overriding-Names.html

Ещё вопросы

Сообщество Overcoder
Наверх
Меню