(ПРИМЕЧАНИЕ: оригинальный пост был слегка отредактирован для улучшения читабельности)
Мы можем использовать JAXB для преобразования объектов Java в XML с использованием заданной схемы и, наоборот, для преобразования XML в объекты Java. Схема XML может быть указана в DTD , XSD или другом формате.
Инструмент «xjc» можно использовать для генерации аннотированных классов Java из схемы XSD. Можно загрузить пакет разработчика веб-служб Java (WSDP) , в него входят необходимые инструменты реализации JAXB. Здесь я расскажу, как динамически генерировать XML.
Пример используемого XSD:
— расход.xsd
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
<?xml version="1.0"?><xs:element name="expenseReport" type="ExpenseT" /><xs:complexType name="ExpenseT"> <xs:sequence> <xs:element name="user" type="UserT"/> <xs:element name="items" type="ItemListT"/> </xs:sequence></xs:complexType><xs:complexType name="UserT"> <xs:sequence> <xs:element name="userName" type="xs:string" /> </xs:sequence></xs:complexType><xs:complexType name="ItemListT"> <xs:sequence> <xs:element name="item" type="ItemT" maxOccurs="unbounded"/> </xs:sequence></xs:complexType><xs:complexType name="ItemT"> <xs:sequence> <xs:element name="itemName" type="xs:string" /> <xs:element name="purchasedOn" type="xs:string" /> <xs:element name="amount" type="xs:decimal" /> </xs:sequence></xs:complexType></xs:schema> |
Теперь мы используем инструмент xjc для генерации соответствующих классов Java. Сгенерированные Java-классы соответствующим образом аннотированы. Я не буду вдаваться в подробности аннотации классов, потому что это усложнит ситуацию.
xjc.exe расход.xsd
По умолчанию команда генерирует классы Java в каталоге с именем «генерируется». Есть много опций, которые можно использовать с xjc, и можно взглянуть на использование
xjc -help
Класс Main ниже использует сгенерированные классы для создания XML.
— Main.java
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
|
package generated; import javax.xml.bind.JAXBContext;import javax.xml.bind.JAXBElement;import javax.xml.bind.JAXBException;import javax.xml.bind.Marshaller;import java.math.BigDecimal; public class Main { public static void main(String[] args) throws JAXBException { ObjectFactory factory = new ObjectFactory(); UserT user = factory.createUserT(); user.setUserName("Sanaulla"); ItemT item = factory.createItemT(); item.setItemName("Seagate External HDD"); item.setPurchasedOn("August 24, 2010"); item.setAmount(new BigDecimal("6776.5")); ItemListT itemList = factory.createItemListT(); itemList.getItem().add(item); ExpenseT expense = factory.createExpenseT(); expense.setUser(user); expense.setItems(itemList); JAXBContext context = JAXBContext.newInstance("generated"); JAXBElement<ExpenseT> element = factory.createExpenseReport(expense); Marshaller marshaller = context.createMarshaller(); marshaller.setProperty("jaxb.formatted.output",Boolean.TRUE); marshaller.marshal(element,System.out); } } |
В приведенном выше XSD мы видим, что объявлено несколько сложных типов. Эти сложные типы генерируются в классах Java. Дочерние элементы и атрибуты становятся свойствами класса, и им предоставляются методы получения и установки. Нельзя напрямую создать экземпляр таких классов, то есть нельзя вызывать для них новые. Всякий раз, когда мы компилируем XSD, генерируется класс ObjectFactory — это фабрика для создания экземпляров сложных типов XSD (строки 17, 19, 24, 27 в приведенном выше классе Java).
Получив экземпляр, мы заполняем свойства соответствующими данными, используя установщики, предоставляемые классом. Также обратите внимание, что сложный элемент может иметь много сложных элементов в качестве членов класса. В этом случае мы используем фабрику, чтобы получить экземпляр сложных элементов, а затем используем установщики внешнего сложного элемента.
Например: в приведенном выше XSD ExpenseT является сложным типом, который состоит из UserT и списка ItemT (ItemListT). В приведенном выше Java-классе (строки 27, 28, 29) мы создаем экземпляр ExpenseT, а затем используем установщики для установки значений UserT и ItemListT. RootElement создается путем вызова createExpenseReport () для фабрики. На имя метода влияют имя корневого элемента и тип возвращаемого значения, а также тип аргумента метода такой же, как и у типа корневого элемента.
После того, как мы установили значения для различных элементов, атрибутов, которые должны входить в XML, пришло время фактически генерировать XML. У нас должен быть Marshaller (для получения XML из объектов Java) или Unmarshaller (для получения объектов Java из XML).
Нам нужен маршаллер, который можно получить из экземпляра JAXBContext . Строки 31,32 получают экземпляр Marshaller. Для маршаллера могут быть установлены разные свойства, и в приведенном выше коде мы устанавливаем jaxb.formatted.output как true, что означает, что полученный XML-файл аккуратно отформатирован, что делает его читаемым для пользователя.
Различные поддерживаемые свойства:
- jaxb.encoding
- jaxb.formatted.output
- jaxb.schemaLocation
- jaxb.noNamespaceSchemaLocation
- jaxb.fragment
<instance_of_marshaller> .marshal () — это метод, используемый для генерации XML. Его перегружают, чтобы принять следующие механизмы вывода:
- org.xml.sax.ContentHandler
- org.w3c.dom.Node
- javax.xml.transform.Result
- java.io.Writer
- java.io.OutputStream
- javax.xml.stream.XMLStreamWriter
- javax.xml.stream.XMLEventWriter
Сгенерированный XML показан ниже:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
|
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <expenseReport> <user> <userName>Sanaulla</userName> </user> <items> <item> <itemName>Seagate External HDD</itemName> <purchasedOn>August 24, 2010</purchasedOn> <amount>6776.5</amount> </item> </items></expenseReport> |
Статьи по Теме: