java - 如果未设置命名空间前缀,则解码对象为 null

标签 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>

通过Spring中的getWebServiceTemplate().marshalSendAndReceive。问题是,我还想在没有命名空间前缀的情况下解码有效负载,如下所示:

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

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

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

  • 解码器是一个 Jaxb2Marshaller

最佳答案

XML 文档

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

XML 架构

elementFormDefault 属性默认为“unqualified”,因此您的架构应匹配第一个文档并拒绝第二个文档。你的实验证实了这一点。 如果您将 elementFormDefault 设置为“qualified”,那么它将拒绝第一个文档并匹配第二个文档。 elementFormDefault 没有任何值可以使 XSD 与两个 XML 文档相匹配。命名空间是元素标识的一个组成部分。

可能的解决方案

如果您决定构建一个与两个文档都匹配的 XSD,则可以按如下方式完成:

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

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

说了以上所有内容...我认为您可能正在解决错误的问题。 JAXB 标准基于 XML 架构。 XSD 并不意味着容忍错误的 namespace 。因此,第二个 XML 文档无效,应该由生成它的人进行更正。

关于java - 如果未设置命名空间前缀,则解码对象为 null,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59143372/

相关文章:

java - 如何仅在 Spring 中通过注释配置组件扫描?

java - 如何使用 jvnet maven-jaxb2-plugin 从类生成 XSD

java - 列表 : pros/cons of this design pattern 中的 JAXB XmlJavaTypeAdapter 映射

java - JaxB - 设置 HexBinary 值

java - RestEasy JAXB - 在 XML 中公开第三方类

java - 如何编写java程序从任何电子邮件ID读取新电子邮件

java - 将 Servlet 中的链接外部化为常量

java - 如何使用 java 或 shell 脚本查找 unix/linux 系统信息?

xml - 如何使 JAXB 使用自定义命名空间前缀

java - 如何使用 JAXB XJC 从外部 XSD 文件生成类