Ich habe einen Web-Service Ich habe einen Proxy nennen erzeugt unter Verwendung mit xcj
(für .xsd
) und wsimport
(für .wsdl
) Definitionen. Es ist extern (d. H. Kann es nicht bearbeiten), riesig und ständig veränderbar (kann die generierten Klassen nicht manuell anpassen).JAX-WS (JAXB) und unmarshalling gemischt xs: anyType
Es hat eine Superklasse-ähnliche xs:anyType
Element mit mixed="true"
, ähnlich wie im Beispiel unten.
<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
erzeugt Foo
als
@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>();
I kann Marshall ein Foo Objekt folgt auf seine wurzel weniger Formular Document.getChildNodes()
(obwohl ich eine sauberere Weg zu finden nichts ausmacht), aber ich kann nicht herausfinden, wie die Antwort content
Liste (die ArrayList<ElementNSImpl>
ist, nachdem Proxy damit fertig ist) zu entpacken Antwort auf stark typisierte 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);
}