我有一个XML模式,它定义了一系列复杂类型,它们是各种命令,响应和事件。
作为一个特例,我有一个Response复杂类型,它由所有响应共有的元素组成,不论其类型如何。然后,我有各种特定类型的回复。有些响应不会添加除Response复杂类型之外的任何其他元素,而其他响应非常复杂并且包含可能复杂或简单的各种其他元素:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="urn:Command" targetNamespace="urn:Command" elementFormDefault="qualified" version="0.0.5.0">
<xs:complexType name="Response">
<xs:annotation>
<xs:documentation>...</xs:documentation>
</xs:annotation>
<xs:sequence>
<xs:element ref="commandID"/>
<xs:element ref="responseToID"/>
<xs:element ref="commandStatus"/>
<xs:element ref="creationTime"/>
<xs:element ref="completionTime"/>
</xs:sequence>
</xs:complexType>
...
<xs:complexType name="SpecificResponse">
<xs:annotation>
<xs:documentation>...</xs:documentation>
</xs:annotation>
<xs:complexContent>
<xs:extension base="Response"/>
</xs:complexContent>
</xs:complexType>
...
当我收到一个包含响应的xs:扩展名的SpecificResponse以及许多其他字段时,XML实际上看起来像:
<Response xsi:type="SpecificResponse" xsi:schemaLocation="urn:Command {file path}" xmlns="urn:Response" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<commandID>...</commandID>
<responseToID>...</responseToID>
<commandStatus>...</commandStatus>
<creationTime>...</creationTime>
<completionTime>...</completionTime>
</Response>
当我在此XML上使用SpecificResponse.Factory.parse(...)
或SpecificResponseDocument.Factory.parse(...)
方法时,由于“元素响应不是有效的SpecificResponse文档或有效替换”,因此失败。在这个特定的例子中,问题不是那么多 - 具有SpecificResponse或SpecificResponseDocument的实例不会为我添加任何新的方法来调用,因为两者中都存在所有字段。但是,在DifferentSpecificResponse包含其他元素的情况下,这是有问题的。另外,当我将它们添加到可以包含任何扩展Response的数据结构时,我宁愿拥有更准确的类型信息。
完整文档在针对架构的外部工具中进行验证。尽管它具有SpecificResponse的所有元素(未在Response元素中定义),但似乎具有xsi:类型的SpecificResponse使XML有效(这是一个不正确的假设吗?)。但是,它看起来像XMLBeans正在查看根元素而不是我想要解析的XML的xsi:类型。
到目前为止,我发现的解决方案是使用ResponseDocument.Factory.parse(...)
解析响应,然后在其上调用getResponse()
函数,然后键入将其转换为适当的特定响应。这对我来说似乎非常笨拙,但是一旦我完成了转换,我可以使用XMLBeans访问器和mutator方法,以及它的类层次结构(这是我所期望的 - 一个SpecificResponse是Response的子类)。是否有更好的方法来处理此问题,假设无法更改消息来源以发送XML <SpecificResponse...
并且必须继续发送<Response xsi:type="SpecificResponse"...