当前位置: 首页 > 知识库问答 >
问题:

JAXB Impl在编组的xml中生成不正确的命名空间

邹英发
2023-03-14

我使用JAXB根据定义的模式封送/解封xml文档。我注意到的是,JAXB在编组的xml中生成了不正确的名称空间。

以下是详细信息-

soap.xsd--

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
    xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope" 
    xmlns:svc="http://abc.com/ServiceSetupV001"
    targetNamespace="http://schemas.xmlsoap.org/soap/envelope"
    elementFormDefault="qualified" attributeFormDefault="unqualified">

    <xsd:import namespace="http://abc.com/ServiceSetupV001" schemaLocation="schema1.xsd" />

    <xsd:complexType name="Envelope">
        <xsd:sequence minOccurs="0" maxOccurs="1">
            <xsd:element name="Body" type="soapenv:Body" minOccurs="0" maxOccurs="1" />
        </xsd:sequence>
    </xsd:complexType>

    <xsd:complexType name="Body">
        <xsd:sequence minOccurs="0" maxOccurs="1">
            <xsd:element name="detailsRequest" type="svc:DetailsRequest" minOccurs="0" maxOccurs="1"/>
            <xsd:element name="detailsResponse" type="svc:DetailsResponse" minOccurs="0" maxOccurs="1" />
        </xsd:sequence>
    </xsd:complexType>

</xsd:schema>

方案1.xsd--

<xsd:schema 
    xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
    targetNamespace="http://abc.com/ServiceSetupV001" 
    xmlns:svc="http://abc.com/ServiceSetupV001" 
    xmlns:osa="http://abc.com/xmlschema/osa" 
    elementFormDefault="qualified" attributeFormDefault="unqualified">

    <xsd:import namespace="http://abc.com/xmlschema/osa" schemaLocation="schema2.xsd"/>

    <xsd:complexType name="DetailsRequest">
        <xsd:sequence minOccurs="0" maxOccurs="1">
            <xsd:element name="requestHeader" type="osa:RequestHeader" />
        </xsd:sequence>
    </xsd:complexType>

    <xsd:element name="detailsRequest" type="svc:DetailsRequest" />

    <xsd:complexType name="DetailsResponse">
        <xsd:sequence minOccurs="0" maxOccurs="1">
            <xsd:element name="responseHeader" type="osa:ResponseHeader" />
        </xsd:sequence>
    </xsd:complexType>

    <xsd:element name="detailsResponse" type="svc:DetailsResponse" />

</xsd:schema>

schema2.xsd--

 <xsd:schema xmlns="http://www.w3.org/2001/XMLSchema" 
        xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
        xmlns:osa="http://abc.com/xmlschema/osa" 
        targetNamespace="http://abc.com/xmlschema/osa" 
        elementFormDefault="qualified" attributeFormDefault="unqualified">

        <xsd:complexType name="RequestHeader">
            <xsd:sequence>
                <xsd:element name="component" type="string" />
                <xsd:element name="channel" type="string" />
                <xsd:element name="serverInstance" type="string" minOccurs="0" />
                <xsd:element name="traceId" type="string" />
                <xsd:element name="applicationId" type="string" />
                <xsd:element name="userId" type="string" minOccurs="0" />
                <xsd:element name="userIdType" type="string" minOccurs="0" />
                <xsd:element name="role" type="string" minOccurs="0" />
                <xsd:element name="timestamp" type="dateTime" minOccurs="0" />
                <xsd:element name="isReplyExpected" type="boolean" minOccurs="0" />
            </xsd:sequence>
        </xsd:complexType>

        <xsd:complexType name="ResponseHeader">
            <xsd:sequence>
                <xsd:element name="component" type="string" />
                <xsd:element ref="osa:service" />
                <xsd:element name="traceId" type="string" />
                <xsd:element name="serverInstance" type="string" />
                <xsd:element name="timestamp" type="dateTime" />
            </xsd:sequence>
        </xsd:complexType>

        <xsd:element name="service" type="osa:Service" />
        <xsd:complexType name="Service">
            <xsd:sequence>
                <xsd:element name="name" type="string" />
                <xsd:element name="operation" type="string" />
                <xsd:element name="version" type="string" />
            </xsd:sequence>
        </xsd:complexType>  

    </xsd:schema>

我为jaxbMarshaller(在我的Spring配置中)定义了一个命名空间Prefix MapperImpl,它将URI映射到我定义的前缀名称。

编组的响应xml如下所示。请注意,JAXB在命名空间前缀上弄错了。JAXB使用soapenv命名空间来获取详细信息响应复杂类型,而不是svc前缀。然后它使用svc前缀来获取响应头复杂类型,而不是osa前缀。某些元素是字符串类型,因此应该没有前缀(即默认命名空间)。等等...

我哪里出错了?或者这是jaxb impl的问题。

生成的XML--

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope"
xmlns:osa="http://abc.com/xmlschema/osa"
xmlns:svc="http://abc.com/ServiceSetupV001">
    <soapenv:Body>
        <soapenv:detailsResponse>
            <svc:responseHeader>
                <osa:component/>
                <osa:service/>
                <osa:traceId>sadasdas</osa:traceId>
                <osa:serverInstance>40d501</osa:serverInstance>
                <osa:timestamp>2012-07-01T02:18:00.693Z</osa:timestamp>
            </svc:responseHeader>
        </soapenv:detailsResponse>
    </soapenv:Body>
</soapenv:Envelope>

我用来从模式生成JAXB类的插件在我的pom中定义。xml如下:

<!-- Plugin to generate jaxb classes from xsd -->
<plugin>
    <groupId>org.jvnet.jaxb2.maven2</groupId>
    <artifactId>maven-jaxb2-plugin</artifactId>
    <version>0.8.2</version>
    <executions>
        <execution>
            <id>process-xsd</id>
            <goals>
                <goal>generate</goal>
            </goals>
            <phase>generate-sources</phase>
            <configuration>
                <schemaIncludes>
                    <include>**/*.xsd</include>
                </schemaIncludes>
                <bindingIncludes>
                    <include>**/*.xjb</include>
                </bindingIncludes>
                <generateDirectory>${src.dir}</generateDirectory>
                    <verbose>true</verbose>
                <extension>true</extension>
                <args>
                    <arg>-Xannotate</arg>
                </args>
                <plugins>
                    <plugin>
                        <groupId>org.jvnet.jaxb2_commons</groupId>
                        <artifactId>jaxb2-basics-annotate</artifactId>
                        <version>0.6.4</version>
                    </plugin>
                </plugins>
            </configuration>
        </execution>
    </executions>
    <dependencies>
        <dependency>
            <groupId>javax.xml.bind</groupId>
            <artifactId>jaxb-api</artifactId>
            <version>2.2.6</version>
        </dependency>
        <dependency>
            <groupId>com.sun.xml.bind</groupId>
            <artifactId>jaxb-impl</artifactId>
            <version>2.2.6</version>
        </dependency>       
        <dependency>
            <groupId>javax.activation</groupId>
            <artifactId>activation</artifactId>
            <version>1.1.1</version>
        </dependency>
        <dependency>
            <groupId>stax</groupId>
            <artifactId>stax-api</artifactId>
            <version>1.0.1</version>
        </dependency>
        <dependency>
            <groupId>activesoap</groupId>
            <artifactId>jaxb-xercesImpl</artifactId>
            <version>1.5</version>
        </dependency>                   
    </dependencies>             
</plugin>

共有1个答案

史同化
2023-03-14

看起来Jaxb为导入的子元素保留了包含xsd的目标命名空间,即使这些导入的子元素有自己的命名空间。解决这个问题的一种方法是将模式中导入元素的定义从“type”更改为“ref”。

但是,在这种情况下,我不想修改模式,因为它们来自客户端,因此我们不想修改它们以使其工作。

因此,我在绑定中添加了以下注释。xjb文件。我现在可以看到,生成的模式类中的元素具有正确的命名空间声明。但是,现在的问题是,生成的xml不会生成子元素,即使名称空间现在是正确的。

所以,我又有点卡住了。我没想到这会这么难。

对我的绑定的更改。xjb:

<jaxb:bindings node="//xsd:complexType[@name='Body']//xsd:element[@name='detailsRequest']">
    <annox:annotate target="field">
    <annox:annotate annox:class="javax.xml.bind.annotation.XmlElement" 
        name="detailsRequest" 
        namespace="http://abc.com/ServiceSetupV001"/>
    </annox:annotate>            
<jaxb:bindings node="//xsd:complexType[@name='Body']//xsd:element[@name='detailsResponse']">
    <annox:annotate target="field">
    <annox:annotate annox:class="javax.xml.bind.annotation.XmlElement" 
        name="detailsResponse" 
        namespace="http://abc.com/ServiceSetupV001"/>
    </annox:annotate>            
</jaxb:bindings>        

<jaxb:bindings node="//xsd:complexType[@name='DetailsRequest']//xsd:element[@name='requestHeader']">
    <annox:annotate target="field">
    <annox:annotate annox:class="javax.xml.bind.annotation.XmlElement" 
        name="requestHeader" 
        namespace="http://abc.com/xmlschema/osa"/>
    </annox:annotate>            
<jaxb:bindings node="//xsd:complexType[@name='DetailsResponse']//xsd:element[@name='responseHeader']">
    <annox:annotate target="field">
    <annox:annotate annox:class="javax.xml.bind.annotation.XmlElement" 
        name="responseHeader" 
        namespace="http://abc.com/xmlschema/osa"/>
    </annox:annotate>            
</jaxb:bindings>

生成的类具有适当的命名空间注释

@XmlElement(name = "detailsRequest", namespace = "http://abc.com/ServiceSetupV001")
protected DetailsRequest detailsRequest;

@XmlElement(name = "detailsResponse", namespace = "http://abc.com/ServiceSetupV001")
protected DetailsResponse detailsResponse;

但是现在,编组的XML没有值

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope"
xmlns:osa="http://abc.com/xmlschema/osa"
xmlns:svc="http://abc.com/ServiceSetupV001">
    <soapenv:Body>
        <svc:detailsResponse/>
    </soapenv:Body>
</soapenv:Envelope>
 类似资料:
  • 我有一个XML要与JAXB解组。如果我从元素中删除所有名称空间属性,代码运行良好,但是如果我保留名称空间属性的话,在解组后会得到一个空对象。 XML是这样的: 我的动物豆是这样的: 猫豆就像: 在运行时,我得到一个空对象。我试图从属性中删除< code>"z:",得到了这个异常: 如果我从猫和动物中删除命名空间,我会得到这个例外: 下面是解组的最终代码。最后一行给出了一个空指针异常 我不确定如何处

  • 抱歉,如果我问的是新手问题,但名称空间对我来说真的很费解。 我试图从一个XML/XSLT生成多个SVG文档。 我的样式表: 这样做会产生以下输出: 但我希望能够根据计算的内容指定高度和宽度属性 我尝试将“ ”创建为 http://www.w3.org/2000/svg 这将失败,因为它(xmlspy)不允许我分配xmlns属性。 如果不在根(svg)上指定名称空间,则xmlns将自动添加到根 节点

  • 我正在从jaxb模型生成rest响应(使用Jersey)。对于某些响应,生成的XML将名称空间前缀(ns2)添加到名称空间属性中,尽管它们都存在于同一个名称空间中。但对其他人来说,这完全没问题。 根据我的分析,我认为当一个复杂元素(另一个jaxb模型)在其中使用时会发生这种情况。但所有这些模型都在package-info.java中的相同名称空间中声明。 这是代码。 XYZModel.class

  • 我正在使用JAXB生成用于编组/解组XML的类。问题是父类的命名空间仅适用于XML中的父元素,而不适用于JAXB注释类中使用的子类。 我不知道我犯了什么错误。下面是我的xsd和xml以及类。 XSD: 项目Responses.xsd JAXB类 项目响应.java 项目响应.java Money.java XML输出: 包信息。java有以下条目 货币类别不在同一个包中。如何将其包含在 Jaxb

  • 我已经阅读了man页面,但我不明白name和namespace是用来做什么的。 对于版本3和版本5的UUID,必须给出额外的命令行参数命名空间和名称。命名空间要么是字符串表示中的UUID,要么是内部预定义命名空间UUID的标识符(目前已知的是“ns: DNS”、“ns: URL”、“ns: OID”和“ns: X500”)。名称是任意长度的字符串。 命名空间: 命名空间可以是字符串表示形式的UUI

  • 我刚刚开始使用Google Protocol Buffers和Marc Gravell的很棒的protobuf net程序,有一件事我不明白,那就是生成的文件中字段声明的命名约定。原始文件。 以下是谷歌的建议: “将下划线_分隔的_名称用作字段名称–例如,song_名称。”https://developers.google.com/protocol-buffers/docs/style "请注意,