#java #xml #jaxb #xsd
#java #xml #jaxb #xsd
Вопрос:
я начал небольшой новый проект и хочу десериализовать объекты из XML.
я создал xsd:
и пример XML-файла :
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<hdb>
<country code="DE">
<variableHoliday daysAfterEaster="49" name="PENTECOAST" />
<fixedHoliday month="JANUARY" day="1" name="NEWYEAR" />
<region code="sa">
<fixedHoliday month="APRIL" day="1" name="FUNNYDAY" />
<variableHoliday daysAfterEaster="0" name="EASTERSUNDAY" />
</region>
<region code="ba">
<variableHoliday daysAfterEaster="12" name="CORPUSCHRISTI" />
</region>
</country>
<country code="US">
<fixedHoliday month="JULY" day="4" name="INDEPENDENCEDAY" />
</country>
<country code="AL">
<fixedHoliday month="JULY" day="4" name="INDEPENDENCEDAY" />
</country>
</hdb>
Который должен использовать xsd и так далее.
Итак, как я могу добиться десериализации этих XML в приятную структуру Java-объекта?
Mabe нравится :
class HDB {
private HashMap<CountryCode,Country> map;
}
class Country {
private List<Holiday> list; // or two Lists with <variableHoliday> and <fixedHoliday>
private List<Region> regions;
}
class Region{
private List<Holiday> list; // or two Lists with <variableHoliday> and <fixedHoliday>
}
class variableHoliday {
private String name;
private int daysAfterEaster;
}
class fixedHoliday {
private String name;
private int day;
private MonthName month; // while MonthName is an enum defined like the enum from XSD
}
Есть идеи, как этого легко достичь?
Я подумал о jaxb и попробовал кое-что, но мне кажется (я новичок в jaxb), что трудно реализовать эту структуру XML из-за того, что карты не могут быть написаны как v.
Ответ №1:
использовать
xjc your_xsd_name -p packagename
для генерации Pojos xjc — это компилятор xml java, который поставляется с jdk.
после создания ваших классов используйте jaxb следующим образом
Сортировка JAXB
HDB hdb = new HDB();
JAXBContext jaxbContext = JAXBContext.newInstance(HDB.class);
Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
jaxbMarshaller.marshal(hdb, file);
jaxbMarshaller.marshal(hdb, System.out);
JAXB разархивирует
File file = new File("your xml file");
JAXBContext jaxbContext = JAXBContext.newInstance(hdb.class);
Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
HDB hdb = (HDB) jaxbUnmarshaller.unmarshal(file);
System.out.println(hdb);
Посетите следующую ссылку для получения дополнительной информации о маршалировании и отмене маршалинга JAXB
Комментарии:
1. вау, великий человек, я не знал этого инструмента. это действительно отличная работа o.O, спасибо!!
2. нужно добавить аннотации JAXB XmlRootElement, XmlAttribute и XmlElement к установщикам классов POJO, чтобы позволить JAXB mapping engine выполнять свои функции.
Ответ №2:
JAXB — привязка Java к XML — это способ эффективного преобразования XML в POJO и наоборот, как указано в приведенном выше примере.
Кроме того, необходимые инструменты поставляются в комплекте с JDK, единственным требованием является безошибочный XSD / набор XSD, необходимый для создания привязок объектов.
XJC
xjc: с использованием аргументов командной строки в виде -p для имени пакета -d для каталога вывода и т.д. Подробности можно найти на странице руководства xjc / на онлайн-странице.
Но если реализация включает в себя несколько xsd, то предпочтительнее использовать xjb (файл привязки)
<jxb:bindings xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
version="2.1" jxb:extensionBindingPrefixes="xjc">
<jxb:globalBindings>
<xjc:simple/>
</jxb:globalBindings>
<jxb:bindings schemaLocation="schema/xml/xmldsig-core-schema.xsd">
<jxb:schemaBindings>
<jxb:package name="org.w3.xmldsig"/>
</jxb:schemaBindings>
</jxb:bindings>
<jxb:bindings schemaLocation="schema/xml/xenc-schema.xsd">
<jxb:schemaBindings>
<jxb:package name="org.w3.xenc"/>
</jxb:schemaBindings>
</jxb:bindings>
</jxb:bindings>
Подробное руководство от oracle по руководству по XJBs
После того, как вы сгенерируете свои привязки, все, что вам нужно, это создать JAXBContext
либо класс, либо список пакетов, разделенных :
final JAXBContext context = JAXBContext.newInstance(Generated.class);
final JAXBContext contextOnPackage = JAXBContext.newInstance("com.alpha.generated:com.beta.generated");
при желании вы также можете предоставить Classloader
окончательный JAXBContext contextCustomClassLoader = JAXBContext.newInstnace(«..:..», X.class.getClassLoader()); // это для более продвинутого использования.
Отмена сортировки
// source can be a file/InputStream/InputSource etc.
Test obj = (Test)context.createUnMarshaller().unmarshal(source);
Сортировка
Test test = gen.xml.package.ObjectFactory.createTest();
// Bunch of setters
// gen.xml.package is generated package XJC will create ObjectFactory as well
// sink can be File/OutputStream/Writer etc.
context.createMarshaller().marshal(test, sink);
Для получения более подробной информации обратитесь к спецификациям Javadocs и JAXB.