@用@XmlJavaTypeAdapters标记的XmlElements?
我有这种情况@用@XmlJavaTypeAdapters标记的XmlElements?,java,xml,xml-serialization,jaxb,jaxb2,Java,Xml,Xml Serialization,Jaxb,Jaxb2,我有这种情况 @XmlType(name ="", propOrder={"value"}) @XmlRootElement(name = "compound") public class Compound extends Value { @XmlElements({ @XmlElement(name="simple", type=Simple.class), @XmlElement(name="compound", type=Compound.class) }) prote
@XmlType(name ="", propOrder={"value"})
@XmlRootElement(name = "compound")
public class Compound extends Value {
@XmlElements({
@XmlElement(name="simple", type=Simple.class),
@XmlElement(name="compound", type=Compound.class)
})
protected List<Value> value;
// ...
}
Simple是一个用适配器标记的类,用于封送/取消封送到简单字符串或从简单字符串封送/取消封送
@XmlJavaTypeAdapter(SimpleAdapter.class)
public class Simple extends Value {
private java.lang.String simple;
// ...
}
化合物不需要适配器
问题是,如果我使用简单的“原样”,它会正确地封送/解封为
<simple>my.text.here</simple>
我如何获得像这样的编组输出
<simple>
my.inner.text.here
</simple>
我的内文在这里
而不是
<simple>
<value>my.inner.text.here</value>
</simple>
我的内文在这里
?听起来您想要
私有java.lang.String innerText
是简单类的@XmlValue。尝试使用@XmlValue标记在Simple中注释字符串:
@XmlRootElement("simple")
public class Simple {
@XmlValue
private java.lang.String innerText;
//getters/setters
}
@XmlValue
public java.lang.String getInnerText() {
return innerText;
}
或者,如果您在getter方法上使用注释(我根据问题中的XML输出假设),请将@XmlElement标记更改为@XmlValue标记:
@XmlRootElement("simple")
public class Simple {
@XmlValue
private java.lang.String innerText;
//getters/setters
}
@XmlValue
public java.lang.String getInnerText() {
return innerText;
}
当我这样做的时候,我得到了您在编辑的问题中所寻找的输出。是正确的,但是您看到的异常是由于JAXB参考实现中的一个错误。该错误也存在于中,但已在2.3.0流中修复,可以在此处获得夜间下载:
import javax.xml.bind.annotation.adapters.XmlAdapter;
public class SimpleAdapter extends XmlAdapter<String, Simple> {
@Override
public Simple unmarshal(String v) throws Exception {
Simple simple = new Simple();
simple.setSimple(v);
return simple;
}
@Override
public String marshal(Simple v) throws Exception {
return v.getSimple();
}
}
化合物
import java.util.List;
import javax.xml.bind.annotation.*;
@XmlRootElement(name = "compound")
@XmlAccessorType(XmlAccessType.FIELD)
public class Compound extends Value {
@XmlElements({ @XmlElement(name = "simple", type = Simple.class),
@XmlElement(name = "compound", type = Compound.class) })
protected List<Value> value;
public List<Value> getValue() {
return value;
}
public void setValue(List<Value> value) {
this.value = value;
}
}
演示
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(Compound.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();
Compound compound = (Compound) unmarshaller.unmarshal(new File("input.xml"));
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(compound, System.out);
}
}
input.xml
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<compound>
<simple>
<simple>FOO</simple>
</simple>
<compound/>
</compound>
福
一件小事。您编写了复合和简单继承自值,但这并没有反映在它们的定义中。另一件事。您确定在复合
中编组的输出是我的.text。这里是而不是我的.text。这里是
?我理解后者,但我不理解我不明白为什么会发生前者。定义的值
元素名称在哪里?总之,看起来您的模型要大得多,您正在手动提取最关键的内容并发布在这里。我不确定您是否运行了它们。如果您提取了一个简单的示例(如您尝试的那样),可能会更好,运行它,并与我们共享整个上下文和结果?你是对的,这只是一个更大的生成(和大量编辑)的摘录我不允许发布的架构。无论如何,我将尝试制作一个简单的测试用例来说明我的意思。我编辑了示例以修复继承,不,我不知道“值”来自何处。我发布这些注释的原因是尝试了一些我认为符合您描述的内容,但我的结果不同。与往常一样,这些e重要的细节。我完全理解发布整个模型可能是不可能的,但即使是可能的,它也不会构成一个好的示例。谢谢,现在问题是另一个问题…简单类扩展了一个抽象基类,称为Value。当我试着对它进行马歇尔分析时,我得到如下结果“无法使用XmlValue对属性或字段s进行注释,因为它是另一个类的子类"。我如何解决这个问题?好的,将@xmltransive
添加到Value类中。这应该可以解决问题。@ciosbel您是否尝试了Value
类上的@xmltransive
注释?它给了我您在上面提供的实现中想要的结果。这正是我最初的想法,但我不想要简单的注释要像您的输入文件一样进行编组,而不使用内部包装器。@ciosbel-我相信您看到的行为是一个bug,我目前正在尝试在EclipseLink JAXB(MOXy)中修复此行为。但是,如果您确实使用MOXy,您可以只使用@XmlValue
,而不使用@XmlJavaTypeAdapter
。@ciosbel-您可以在EclipseLink JAXB(MOXy)中跟踪此问题的进展通过以下错误:这是一个错误。谢谢。如果没有问题,我将尝试切换到MOXy实现并测试@XmlValue提示。
import java.io.Serializable;
public abstract class Value implements Serializable {}
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(Compound.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();
Compound compound = (Compound) unmarshaller.unmarshal(new File("input.xml"));
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(compound, System.out);
}
}
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<compound>
<simple>
<simple>FOO</simple>
</simple>
<compound/>
</compound>