使用 JAXB 解组 XML

Unmarshalling an XML with JAXB

提问人:Maxim 提问时间:10/23/2023 更新时间:10/23/2023 访问量:45

问:

我有一些生成的类,看起来像这样:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "Data", propOrder = {
    "body"
})
@XmlRootElement(name = "Data")
class Data {
    @XmlElement(name = "Body", required = true)
    protected Body body;
    // getter and setter
}

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "Body", propOrder = {
    "content"
})
class Body {
    @XmlMixed
    @XmlAnyElement
    protected List<Object> content; 
    // getter
}

以及 XML 类型的其他一些类:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "Node1", propOrder = {
    "data",
})
class Node1 {
   @XmlElement(name = "Data")
   private String data;
}

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "Node2", propOrder = {
    "int",
})
class Node2 {
   @XmlElement(name = "Int")
   private Integer int;
}

XML 示例为:

<Data>
    <Body>
        <Node1>
           <Data>abc</Data>
        </Node1>
        <Node2>
           <Int>abc</Int>
        </Node2>
    </Body>
</Data>

当我尝试取消 XML 的 XML,它返回一个 ,并且 中的一些元素是 类型 ,其他元素只是带有新行的字符串。JAXBElement<Data>Body.contentElementNSimpl

这是我解组 XML 的方式:

private Object xmlToObject(String xmlString) throws Exception {
        var context = JAXBContext.newInstance(Data.class, Node1.class, Node2.class);
        var unmarshaller = context.createUnmarshaller();
        return unmarshaller.unmarshal(new StringReader(xmlString));
    }

我希望收到一个对象,它将包含该对象,并且该对象将包含两个元素,并且,但正如我所说,其中的元素是,DataBodyBodyNode1Node2Body.conentElementNSimpl

Java XML JAXB

评论

0赞 LMC 10/23/2023
可能是它被重复的数据元素混淆了。尝试将类型添加到最后一个/Data/Body/Node1/Data@XmlElement(name = "Data", type=String.class)
0赞 Maxim 10/23/2023
对不起,没有。这些只是例子。实际类有不同的名称,没有冲突。

答:

2赞 forty-two 10/23/2023 #1

在取消封送时获得 JAXBElement,表示您的模式包含 2 个或多个相同复杂类型的全局元素。有关更深入的解释,请参阅文章。

当我尝试您的示例时,我确实直接获得了一个 Data 实例。没有 JAXBElement 包装器。

要在 @Mixed @XmlAnyElement list 属性中获取映射的类实例,需要用 @XmlRootElement 对映射的 Java 类进行注释,并且@XmlAnyElement必须将其 lax 属性设置为 true(请参阅 javadoc)。

评论

0赞 Maxim 10/23/2023
谢谢!它有帮助。我用来获取域模型而不是包装器。此外,将 lax 属性设置为 true,有助于获取域模型实例而不是 .我仍然有一些 String 元素,但我认为我可以遍历它们并获得我需要的项目。JAXBIntrospector.getValue()ElementNSimplBody.content