Маршаллинг и демаршаллинг Java

Employee.xsd

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:jxb="http://java.sun.com/xml/ns/jaxb" jxb:version="1.0" elementFormDefault="qualified">
<xsd:include schemaLocation="Family.xsd"/>
    <xsd:element name="NewFields">
        <xsd:complexType>
            <xsd:sequence>
                <xsd:element name="empFirstName" type="xsd:string" />
                <xsd:element name="empLastName" type="xsd:string" />
                <xsd:element name="family" type="FamilyFields" nillable="true" maxOccurs="unbounded" minOccurs="0"/>
            </xsd:sequence>
        </xsd:complexType>
    </xsd:element>
</xsd:schema>

Family.xsd

<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:jxb="http://java.sun.com/xml/ns/jaxb" jxb:version="1.0" elementFormDefault="qualified">
<xsd:complexType name="FamilyFields">
        <xsd:sequence>
            <xsd:element name="relation" type="xsd:string" />
            <xsd:element name="firstName" type="xsd:string" />
            <xsd:element name="lastName" type="xsd:string"/>
        </xsd:sequence>
</xsd:complexType>  
</xsd:schema>

Стороннее приложение, использующее эти 2 схемы, генерирует строку xml, например:

<NewFields>
    <empFirstName>Kevin</empFirstName>
    <empLastName>Smith</empLastName>
    <family>
        <FamilyFields>
            <relation>self</relation>
            <firstName>New Kevin</firstName>
            <lastName>New Smith</lastName>
        </FamilyFields>
        <FamilyFields>
            <relation>wife</relation>
            <firstName>Jennifer</firstName>
            <lastName>Smith</lastName>
        </FamilyFields>
    </family>
</NewFields>

Вторая схема - это всегда фиксированная схема.

Мое требование - проанализировать тег отношения, и если отношение является «самим», мне нужно перезаписать empFirstName и empLastName с помощью firstName и lastName соответствующих полей.

Как я могу этого добиться?

РЕДАКТИРОВАТЬ 1: Employee.xsd является динамическим и может быть любым. Но Family.xsd статичен и может быть импортирован из любого другого xsd.


person jagamot    schedule 30.09.2011    source источник


Ответы (2)


Общий план: (a) сопоставить вам файлы схемы XML, (b) демаршалировать данный XML, (c) изменить объект XML в памяти finally (d) маршалируйте измененный объект в любом месте.

Сопоставьте файлы схемы XML

@XmlRootElement(name = "FamilyFields") public class FamilyFields {

  @XmlElement public String relation;
  @XmlElement public String firstName;
  @XmlElement public String lastName;

  public FamilyFields() {}
}

@XmlRootElement(name = "NewFields") public class NewFields {

  @XmlElement public String empFirstName;
  @XmlElement public String empLastName;
  @XmlElementWrapper(name = "family")
  @XmlElement(name = "FamilyFields")
  public List<FamilyFields> familyFields;

  public NewFields() {}
}

(Если вы прислушаетесь к совету: делайте это вручную! Создание объектов JAXB с помощью XJC почти никогда не приводит к ожидаемым результатам и может занять много времени, если у вас нет очень простых файлов схемы в рука.)

Приобретите JAXBContext, Unmarshaller и Marshaller

JAXBContext context = JAXBContext.newInstance(NewFields.class, FamilyFields.class);
Unmarshaller unmarshaller = context.createUnmarshaller();
Marshaller marshaller = context.createMarshaller();
// set optional properties
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);

Обработка входящего XML

// the XML content you gave
String xml = ...

StringReader reader = new StringReader(xml);
NewFields newFields = (NewFields) unmarshaller.unmarshal(reader);

// modify the unmarshalled data to your heart's content
newFields.empLastName = ...

// marshal the modified data anywhere you want
marshaller.marshal(newFields, System.out);
person Kohányi Róbert    schedule 30.09.2011
comment
если у моего xml есть массив FamilyFields, похоже, он не работает! Кроме того, я вижу какое-то исключение с приведенным выше кодом ... что-то вроде - javax.xml.bind.UnmarshalException: неожиданный элемент (uri :, local: family). Ожидаемые элементы (неизвестны) - person jagamot; 04.10.2011
comment
Я скопировал ваши два объявления схемы и протестировал XML, и они работали на меня. Если вы получаете unexpected element исключение, возможно, XML, который вы пытаетесь демаршалировать / маршаллировать, имеет объявления пространства имен XML. Это могло быть проблемой. (Если вы разместите свой XML где-нибудь, например pastebin, я могу взглянуть на него.) - person Kohányi Róbert; 04.10.2011
comment
Кстати, в своих тестах я использовал JAXB 2.2.4-1. - person Kohányi Róbert; 04.10.2011
comment
Вы правы, я пропустил добавление аннотации XMLROOTElement в класс FamilyFields! Благодарю вас! - person jagamot; 04.10.2011

Если у вас есть XSD, то манипулировать XML проще всего с помощью привязки данных XML. Используя XSD, вы можете создавать Java-bean-подобные классы, представляющие XSD. Теперь вы можете получить и установить в классе java, а затем вывести XML. Существует множество решений для привязки данных XML. Попробуйте бины XML:

http://xmlbeans.apache.org/

person sethu    schedule 30.09.2011