注释向元素添加属性

时间:2010-11-16 09:30:04

标签: jaxb

我正在以这种精神升级当前具有XML表示的Java对象:

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

myElement 是可选的 - 它在Java中可以为null /在XML中省略 如果 myElement 具有实际值,我会添加相关的字段 (并保持与以前的XML的兼容性,它本身是可选的)

我试图避免这种情况:

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

并喜欢这样的事情:

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

但是我现在已经开了两天关于如何注释它。

  • 我想用 XmlTransient 标记它并让 XmlAnyElement 在解组时捕获它 - 但是当将对象从Java编组回来时这似乎会导致问题XML。
  • 我尝试为元素创建 XmlAdapter - 但是unmarshal方法只获取内部内容(“some_string”)。 我是否遗漏了这项技术?
  • 有没有办法只是将元素作为字符串(“&lt; myElement myAttr = \”foo \“&gt; some_string&lt; / myElement&gt;”),我将处理我自己?
  • 您是否建议使用其他方法?

2 个答案:

答案 0 :(得分:3)

您可以使用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

有关MOXy基于XPath的映射的更多信息,请参阅:

答案 1 :(得分:1)

答案很简单:我已经习惯用 XmlElement XmlAttribute 进行注释,我忘了 XmlValue

MyObject 的代码与Blaise Doughan的答案相同,只有一处变化: myElement 现在是一个类( ElemWithAttr )而不是String:

public class ElemWithAttr {
    @XmlValue
    public String content;

    @XmlAttribute
    public String myAttr;
}