gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-04 00:00:30 26 4
gpt4 key购买 nike

我正在使用 JAXB 根​​据定义的模式编码/解码 xml 文档。我注意到 JAXB 在编码的 xml 中生成不正确的 namespace 。

这里是详细信息-

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>

schema1.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 定义了一个 namespacePrefixMapperImpl(在我的 spring 配置中),它将 URI 映射到我定义的前缀名称。

编码的响应 xml 如下所示。请注意,JAXB 在 namespace 前缀上搞砸了。 JAXB 正在使用 soapenv 命名空间对于 detailsResponse 复杂类型,而不是 svc 前缀。然后它使用 svc 前缀作为 responseHeader 复杂类型而不是 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>

最佳答案

好吧,看起来 Jaxb 正在为导入的子元素保留包含 xsd 的目标 namespace ,即使那些导入的子元素有自己的 namespace 。解决此问题的一种方法是将架构中导入元素的定义从“type”更改为“ref”。

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

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

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

对我的 bindings.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>

关于namespaces - JAXB Impl 在编码的 xml 中生成不正确的命名空间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11962835/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com