【发布时间】:2016-04-27 22:16:12
【问题描述】:
我有一个 Web 服务,我必须使用使用 xcj(对于 .xsd)和 wsimport(对于 .wsdl)定义生成的代理进行调用。它是外部的(即无法编辑)、巨大且不断变化的(无法手动调整生成的类)。
它有一个类似于超类的xs:anyType 元素和mixed="true",类似于下面的示例。
<Foo type="Bar">
<id>123</id>
</Foo>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="Foo">
<xs:complexType>
<xs:complexContent mixed="true">
<xs:extension base="xs:anyType">
<xs:attribute name="type" type="xs:string"/>
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:element>
<xs:element name="Bar">
<xs:complexType>
<xs:sequence>
<xs:element name="id" type="xs:int"/>
<xs:element name="name" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
xjc/wsimport生成Foo如下
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = { "content" })
@XmlRootElement(name = "Foo")
public class Foo {
@XmlMixed
@XmlAnyElement
protected List<Object> content;
@XmlAttribute(name = "type")
protected String type;
@XmlAnyAttribute
private Map<QName, String> otherAttributes = new HashMap<QName, String>();
我可以使用 Document.getChildNodes() 将 Foo 对象编组到它的 root-less 形式(虽然我不介意找到更清洁的方法),但我不知道如何解组响应的 @987654333 @list(代理完成后是ArrayList<ElementNSImpl>)到强类型Bar?
public static void main(String[] args) throws Exception {
Foo foo = new Foo();
foo.type = "Bar";
Bar bar = new Bar();
bar.id = 123;
JAXBContext context = JAXBContext.newInstance(Foo.class, Bar.class);
Marshaller marshaller = context.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
marshaller.marshal(bar, document);
NodeList nodes = document.getFirstChild().getChildNodes();
foo.content = IntStream.range(0, nodes.getLength()).mapToObj(nodes::item).collect(Collectors.toList());
StringWriter writer = new StringWriter();
marshaller.marshal(foo, writer);
System.out.println(writer);
Unmarshaller unmarshaller = context.createUnmarshaller();
// ???
unmarshaller.unmarshal(foo.content, Bar.class);
}
【问题讨论】: