аннотирование добавления атрибута к элементу - PullRequest
2 голосов
/ 16 ноября 2010

Я обновляю объект Java, который в настоящее время имеет представление XML в этом духе:

<myObjects>
    <myObject uid="42" type="someEnum">
        <name>Waldo</name>
        <description>yada yada</description>
        <myElement>some_string</myElement>
        ...
    </myObject>
    ...
</myObjects>

myElement является необязательным - он может быть нулевым в Java / опущен в XML.
Я добавляю поле, которое только релевантно, если myElement имеет фактическое значение (и чтобы сохранить совместимость с предыдущим XML, он сам по себе необязателен)

Я пытаюсь избежать этого:

    <myElement>some_string</myElement>
    <myAttr>foo</myAttr>

и предпочитаю что-то вроде этого:

    <myElement myAttr="foo">some_string</myElement>

но уже 2 дня бьюсь головой о том, как это комментировать.

  • Я думал о том, чтобы пометить его XmlTransient и позволить XmlAnyElement перехватить его вместо демаршаллинга - но, похоже, это вызовет проблему при перенаправлении объекта обратно из Java в XML.
  • Я попытался создать XmlAdapter для элемента - но метод unmarshal получает только внутреннее содержимое ("some_string"). Я что-то упустил с этой техникой?
  • Есть ли способ просто получить элемент в виде строки (" some_string "), и я обработаю его сам?
  • Вы рекомендуете какой-либо другой подход?

Ответы [ 2 ]

3 голосов
/ 16 ноября 2010

Вы можете использовать расширение EclipseLink JAXB (MOXy) @XmlPath, чтобы легко сделать это:

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlRootElement;

import org.eclipse.persistence.oxm.annotations.XmlPath;

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class MyObject {

    @XmlAttribute
    private int uid;

    @XmlAttribute
    private String type;

    private String name;

    private String description;

    private String myElement;

    @XmlPath("myElement/@myAttr")
    private String myAttr;

}

Этот класс будет взаимодействовать со следующим XML:

<myObject uid="42" type="someEnum">
    <name>Waldo</name>
    <description>yada yada</description>
    <myElement myAttr="foo">some_string</myElement>
</myObject>

Используя следующий демонстрационный код:

import java.io.File;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;

public class Demo {

    public static void main(String[] args) throws Exception {
        JAXBContext jc = JAXBContext.newInstance(MyObject.class);

        File file = new File("input.xml");
        Unmarshaller unmarshaller = jc.createUnmarshaller();
        MyObject myObject = (MyObject) unmarshaller.unmarshal(file);

        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.marshal(myObject, System.out);
    }

}

Чтобы указать MOXy в качестве реализации JAXB, вам нужно включить файл с именем jaxb.properties в тот же пакет, что и классы модели, со следующей записью:

javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory

Для получения дополнительной информации о сопоставлении на основе XPath MOXy см .:

1 голос
/ 24 ноября 2010

Ответ был очень прост: я так привык аннотировать XmlElement и XmlAttribute , что я забыл о XmlValue !

Код для MyObject такой же, как в ответе Блеза Дафана, с одним изменением: myElement теперь является классом ( ElemWithAttr ) вместо String:

public class ElemWithAttr {
    @XmlValue
    public String content;

    @XmlAttribute
    public String myAttr;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...