Синтаксический анализ / десериализация XML в JavaObjects

#java #xml #jaxb #xsd

#java #xml #jaxb #xsd

Вопрос:

я начал небольшой новый проект и хочу десериализовать объекты из XML.

я создал xsd:

http://pastebin.com/n1pwjRGX

и пример 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.