【问题标题】:annotating the addition of an attribute to an element注释向元素添加属性
【发布时间】:2010-11-16 09:30:04
【问题描述】:

我正在本着这种精神升级一个当前具有 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>

但是现在我花了 2 天时间来讨论如何注释它。

  • 我想用 XmlTransient 标记它,并在解组时让 XmlAnyElement 捕获它 - 但似乎在将对象从 Java 编组回XML。
  • 我尝试为元素创建一个 XmlAdapter - 但 unmarshal 方法只获取内部内容(“some_string”)。 我是否错过了这项技术?
  • 有没有办法将元素作为字符串 ("some_string") 我会自己处理它?强>
  • 您是否推荐任何其他方法?

【问题讨论】:

  • 我们需要看看你的java
  • 如果不清楚 - 我只需要保持与以前的 XML 文件的兼容性。我可以用 Java 代码做任何我想做的事情。所以我故意不提供它,以免给你带来偏见(Blaise Doughan 在下面解释得很好)。

标签: jaxb


【解决方案1】:

您可以使用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 的映射的更多信息,请参阅:

【讨论】:

  • 最终我没有使用您的解决方案(请参阅下面我自己的答案)。但我确实从你的解释和你的博客中学到了很多东西,所以我把它标记为“接受”:-)
【解决方案2】:

答案非常简单:我已经习惯了使用 XmlElementXmlAttribute 进行注释,以至于忘记了 XmlValue! p>

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

public class ElemWithAttr {
    @XmlValue
    public String content;

    @XmlAttribute
    public String myAttr;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-04
    • 1970-01-01
    • 1970-01-01
    • 2011-12-26
    • 1970-01-01
    相关资源
    最近更新 更多