当您不知道引用的元素类型是什么时,如何处理引用?
我有一个元素<input>
,它是一个数据接收器。元素<input>
具有属性source
,其指定(XmlIDREF
引用)数据来自何处。 source
引用的元素可以是多个元素之一。
以下是我正在使用的测试文档中的示例,其中<input>
的{{1}}有时会引用source
元素,有时会引用<source>
(和那些不一定是它可以参考的唯一元素):
<vertices>
如果我这样做
<source id="position">
<float_array id="arrayPosition" count="78">...</float_array>
...
</source>
<source id="normal">
<float_array id="arrayNormal" count="144">...</float_array>
...
</source>
<vertices id="vertex">
<input semantic="POSITION" source="position"/>
</vertices>
<polylist material="MyMaterial" count="40">
<input semantic="VERTEX" source="vertex" offset="0"/>
<input semantic="NORMAL" source="normal" offset="1"/>
...
</polylist>
然后对class Input
{
Source source;
}
元素的所有引用都能正常工作,但对于其余元素,它们的来源是<source>
。也就是说,如果我要设置一个null
来显示类和id并打印上面的输入,我会得到
toString()
第一行将正确引用第一个Source: position
null
Source: normal
元素,第二行(我想引用<source>
元素)将是<vertices>
,第三行将引用第二个null
元素。
如果我要更改<source>
以改为使用字段Input
,那么我会改为Vertices source
null
和Vertices vertex
。这是有道理的。
我如何构建我的Java代码来处理这个问题?
我已经研究过XmlAdapter,想想也许我可以给课程null
一个字段Input
或Object source
(同时创建MySuperClass source
和Source
子类它)或Vertices
,然后尝试转换适配器代码中的东西,但我怎么保留id引用?
我研究了JAXBElement source
和工厂用法,但这似乎根本不是我想要的,或者至少我看不出它是如何应用的,尽管它起初听起来像是一个好的候选人。
谷歌搜索相关术语产生了其他人没有相关的各种引用问题。
我在想,无论如何,两件事中的一件必须是真的:
1)XmlType
和Source
(以及Vertices
可以使用其Input
字段引用的所有其他内容)将必须扩展一个公共超类。
要么
2)source
将有一个Input
和一个Source source1
(依此类推,到Vertices source2
),其中一个会引用一些内容而其他所有内容都将为null
我很满意这两种情况中的任何一种,也可以选择替代方案,只要它解组所有数据并保留引用,这样我就可以获得所有信息。我只是想不出正确的方法来解组它。
我无法控制我得到的xml。 xml文档由其他程序创建,模式遵循大规范(http://www.khronos.org/files/collada_spec_1_4.pdf)。我只编写解组xml所需的Java代码并使用这些文件中的数据。
昨晚我刚刚开始使用jaxb,它的效果非常强(再次向开发者致敬),但有一些挥之不去的事情仍然需要解决。
答案 0 :(得分:1)
<强>根强>
@XmlIDREF
引用的每个对象也需要通过嵌套关系进行引用。它们并不都需要与本例中的同一类引用。
import java.util.List;
import javax.xml.bind.annotation.*;
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Root {
@XmlElementWrapper
@XmlElement(name="foo")
private List<Foo> foos;
@XmlElementWrapper
@XmlElement(name="bar")
private List<Foo> bars;
}
<强>富强>
使用@XmlIDREF
注释的属性将匹配任何类型的任何元素,无论它在文档中出现的位置。
import javax.xml.bind.annotation.*;
@XmlAccessorType(XmlAccessType.FIELD)
public class Foo {
@XmlID
@XmlAttribute
private String id;
@XmlIDREF
@XmlAttribute
private Object reference;
}
<强>酒吧强>
import javax.xml.bind.annotation.*;
@XmlAccessorType(XmlAccessType.FIELD)
public class Bar {
@XmlID
@XmlAttribute
private String id;
}
<强>演示强>
import java.io.File;
import javax.xml.bind.*;
public class Demo {
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(Root.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();
File xml = new File("src/forum17799549/input.xml");
Root root = (Root) unmarshaller.unmarshal(xml);
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(root, System.out);
}
}
<强> input.xml中/输出强>
<?xml version="1.0" encoding="UTF-8"?>
<root>
<foos>
<foo id="B" reference="C"/>
<foo id="A" reference="B"/>
</foos>
<bars>
<bar id="C"/>
</bars>
</root>
了解更多信息