如果未设置名称空间前缀,则未编组对象为null

时间:2019-12-02 16:50:44

标签: java xsd jaxb unmarshalling

我有以下XSD:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           xmlns:x="MY_NAMESPACE"
           targetNamespace="MY_NAMESPACE">

    <xs:element name="response" type="x:responseType"/>

    <xs:complexType name="responseType">
        <xs:all>
            <xs:element name="param" type="x:responseParam"/>
        </xs:all>
    </xs:complexType>

    <xs:complexType name="responseParam">
        <xs:all>
            <xs:element name="value" type="xs:string"/>
        </xs:all>
    </xs:complexType>

</xs:schema>

我使用它来生成JAXB类,以对有效载荷进行解组,如下所示:

<x:response xmlns:x="MY_NAMESPACE">
<param>
<value>OK</value>
</param>
</x:response>

在春季通过getWebServiceTemplate().marshalSendAndReceive。问题是,我也想解组没有名称空间前缀的有效负载,像这样:

<response xmlns="MY_NAMESPACE">
<param>
<value>OK</value>
</param>
</response>

在这种情况下,response标记已正确解析,但是表示param的对象引用始终为null。我如何编辑我的XSD使其正常工作?我已经尝试在架构中设置elementFormDefault="qualified",甚至在form="qualified"元素上设置param

想到的其他信息(我可能会根据评论进行编辑和添加更多内容)

  • 解组器是Jaxb2Marshaller

1 个答案:

答案 0 :(得分:1)

XML文档

我想您可能知道这一点,但是删除该名称空间前缀会影响整个文档(因为'param'和'value'标记没有任何前缀,因此会继承默认的名称空间绑定)。因此,在第一个文档中,根标签“ response”位于名称空间“ MY_NAMESPACE”中,其他标签没有任何名称空间。在第二个文档中,所有标签都位于名称空间“ MY_NAMESPACE”中。

XML模式

elementFormDefault属性默认为'unqualified',因此您的架构应与第一个文档匹配,而拒绝第二个文档。您的实验证实了这一点。 如果将elementFormDefault设置为“ qualified”,则它将拒绝第一个文档并匹配第二个文档。 没有elementFormDefault的值将使XSD匹配两个XML文档。名称空间是元素标识不可或缺的一部分。

可能的解决方案

如果确定要构造一个与两个文档都匹配的XSD,则可以按以下步骤进行操作:

  • 明确地将elementFormDefault设置为“不合格”(可选,但您将依赖于该设置)b
  • 将responseType的当前(全局声明)内容包装在选择组中
  • 在选择组中添加第二个分支,其中包含元素'param'及其所有后代的 local 声明。因为这些是在本地声明的,所以它们将位于noTargetNamespace中。

这不是解决使JAXB忽略名称空间的问题的通用解决方案,而且我认为您不会找到一个(尽管我很高兴被比我更了解JAXB的人加以纠正)。 / p>

以上已经说了所有...我认为您可能正在解决错误的问题。 JAXB标准基于XML Schema。 XSD并不意味着可以容忍错误的名称空间。因此,第二个XML文档是无效的,应该由生成它的任何人进行纠正。