【问题标题】:JAX-WS (JAXB) and unmarshalling mixed xs:anyTypeJAX-WS (JAXB) 和解组混合 xs:anyType
【发布时间】: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&lt;ElementNSImpl&gt;)到强类型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);
}

【问题讨论】:

    标签: java xsd jaxb jax-ws


    【解决方案1】:

    我想我解决了。向提出更清洁解决方案的人投票。

    public static List<Object> marshal(Object value) {
        try {
            Class<?> type = value.getClass();
            if (type.isAnonymousClass())
                type = type.getSuperclass();
    
            Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
            Marshaller marshaller = JAXBContext.newInstance(type).createMarshaller();
            marshaller.marshal(new JAXBElement<>(QName.valueOf("root"), Object.class, value), document);
    
            NodeList nodes = document.getDocumentElement().getChildNodes();
            return IntStream.range(0, nodes.getLength()).mapToObj(nodes::item).collect(Collectors.toList());
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    
    public static <T> T unmarshal(List<Object> content, Map<QName, String> attributes, Class<T> type) {
        try {
            Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
            document.appendChild(document.createElement("root"));
    
            if (attributes != null)
                attributes.forEach((q, s) -> document.getDocumentElement().setAttribute(q.getLocalPart(), s));
    
            if (content != null)
                content.forEach(o -> document.getDocumentElement().appendChild(document.importNode((Node) o, true)));
    
            Unmarshaller unmarshaller = JAXBContext.newInstance(type).createUnmarshaller();
            return unmarshaller.unmarshal(document, type).getValue();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2011-06-29
      • 2011-12-16
      • 2012-05-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-16
      • 2013-11-05
      • 2012-01-05
      相关资源
      最近更新 更多