java - 如何修复 Jaxb 的 xmlMapper "Multiple fields representing property "PS""问题?

标签 java xml jackson jaxb xmlmapper

我使用 Jaxb 从 xsd 生成 Jar 文件:

CustomObject inputRequest = xmlMapper.readValue(input, CustomObject.class); 

我收到的错误消息是:

com.fasterxml.jackson.databind.JsonMappingException: Multiple fields representing property "PS": OrderLineType#pS vs OrderLineType#pSV5 at [Source: (StringReader); line: 1, column: 1]

我的类(class)是:

@XmlElement(name = "PS", namespace = "financetypes:defn:v4")
protected financetypes.v4.PSType pS;
@XmlElement(name = "PS", namespace = "financetypes:defn:v5")
protected financetypes.v5.PSType pSV5;

它们具有相同的名称,但不同的命名空间。

xmlmapper 是否能够处理具有相同名称和不同命名空间的 XmlElement?

如果是,我该如何解决这个问题?如果不是,我该怎么办?

我正在从 jenkin 构建 jar 文件。有没有可以用来解决此问题的插件?

谢谢!

这是我的xsd v4.xsd

    <!--Begin Definition: Complex Type: PriceStructureType-->
<xs:complexType name="PriceStructureType">
    <xs:sequence>
        <xs:element name="PriceModel" type="xs:string" minOccurs="0">
            <xs:annotation>
                <xs:documentation>
                    Will be required in future...
                    TODO: Add valid items...
                </xs:documentation>
            </xs:annotation>
        </xs:element>
        <xs:element ref="finance:SourceSystemPrice" minOccurs="0">
            <xs:annotation>
                <xs:documentation>
                    Will be required in future...
                </xs:documentation>
            </xs:annotation>
        </xs:element>
        <xs:element name="ComponentPrice" type="finance:ComponentListType" minOccurs="0">
            <xs:annotation>
                <xs:documentation>
                    Will be required in future...
                </xs:documentation>
            </xs:annotation>
        </xs:element>
    </xs:sequence>
</xs:complexType>
<xs:element name="PriceStructure" type="finance:PriceStructureType"/>
<!--End Definition: Complex Type: PriceStructureType-->

v5.xsd

    <!--Begin Definition: Complex Type: PriceStructureType-->
<xs:complexType name="PriceStructureType">
    <xs:sequence>
        <xs:element name="PriceModel" type="xs:string" minOccurs="0">
            <xs:annotation>
                <xs:documentation>
                    Will be required in future...
                    TODO: Add valid items...
                </xs:documentation>
            </xs:annotation>
        </xs:element>
        <xs:element ref="finance:SourceSystemPrice" minOccurs="0">
            <xs:annotation>
                <xs:documentation>
                    Will be required in future...
                </xs:documentation>
            </xs:annotation>
        </xs:element>
        <xs:element name="ComponentPrice" type="finance:ComponentListType" minOccurs="0">
            <xs:annotation>
                <xs:documentation>
                    Will be required in future...
                </xs:documentation>
            </xs:annotation>
        </xs:element>
    </xs:sequence>
</xs:complexType>
<xs:element name="PriceStructure" type="finance:PriceStructureType"/>
<!--End Definition: Complex Type: PriceStructureType-->

common.xsd

xmlns:finance="urn:financetypes:defn:v4"
xmlns:finance_v5="urn:financetypes:defn:v5"
<xs:import namespace="urn:financetypes:defn:v4" schemaLocation="financetypes.v4.xsd"/>
<xs:import namespace="urn:financetypes:defn:v5" schemaLocation="financetypes.v5.xsd"/>

<xs:choice>
            <xs:element ref="finance:PriceStructure" minOccurs="0">
                <xs:annotation>
                    <xs:documentation xml:lang="en">
                        Price Structure itemizes the price components of this OrderLine.  Pricing
                        is a integral part of the Sales Order record.
                        This should be a required element for a sales order, but it is marked
                        as optional for backward compatibility. 
                    </xs:documentation>
                </xs:annotation>
            </xs:element>
            <xs:element ref="finance_v5:PriceStructure" minOccurs="0">
                <xs:annotation>
                    <xs:documentation xml:lang="en">
                        Price Structure itemizes the price components of this OrderLine.  Pricing
                        is a integral part of the Sales Order record.
                        This should be a required element for a sales order, but it is marked
                        as optional for backward compatibility. 
                    </xs:documentation>
                    <xs:appinfo>
                        <jaxb:property name="PriceStructureV5"/>
                    </xs:appinfo>
                </xs:annotation>
            </xs:element>
        </xs:choice>

最佳答案

你可以这样做。对于包含这两个元素的根类:

@XmlRootElement(name = "root")
@XmlAccessorType(XmlAccessType.FIELD)
public class Root {

    @XmlElement(name = "PS", namespace = "financetypes:defn:v4")
    protected financetypes.v4.PSType pS;
    @XmlElement(name = "PS", namespace = "financetypes:defn:v5")
    protected financetypes.v5.PSType pSV5;
}

您可以创建具有不同版本的类,如下所示:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "v4PS", namespace = "financetypes:defn:v4")
public class PSType {

    @XmlValue
    private String value;
}

和:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "v5PS", namespace = "financetypes:defn:v5")
public class PSType {

    @XmlValue
    private String value;
}

示例 xml 如下:

<root xmlns:v4="financetypes:defn:v4" xmlns:v5="financetypes:defn:v5">
    <v4:PS>version 4</v4:PS>
    <v5:PS>version 5</v5:PS>
</root>

您将能够正确解码。

更新以回复评论:

您使用 xsd 生成类。您没有提供 xsd,所以我认为您不被允许。我创建了一个 xsd 来生成您在问题中显示的类。命名空间.xsd 如下所示:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:v4="financetypes:defn:v4" xmlns:v5="financetypes:defn:v5">

    <xs:element name="root">
        <xs:complexType>
            <xs:all>
                <xs:element name="v4PSType" type="PSTypev4" />
                <xs:element name="v5PSType" type="PSTypev5" />
            </xs:all>
        </xs:complexType>
    </xs:element>

    <xs:complexType name="PSTypev4">
        <xs:simpleContent>
            <xs:extension base="xs:string" />
        </xs:simpleContent>
    </xs:complexType>

    <xs:complexType name="PSTypev5">
            <xs:simpleContent>
                <xs:extension base="xs:string" />
            </xs:simpleContent>
    </xs:complexType>

</xs:schema>

那么你的绑定(bind)将是:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<jaxb:bindings version="2.0" xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
               xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
               xmlns:xs="http://www.w3.org/2001/XMLSchema"
               xmlns:annox="http://annox.dev.java.net"
               jaxb:extensionBindingPrefixes="xjc">

    <jaxb:bindings schemaLocation="../xsd/namespaces.xsd">
        <jaxb:bindings node="//xs:complexType[@name='PSTypev4']">
            <annox:annotate target = "class">
                <annox:annotate annox:class="javax.xml.bind.annotation.XmlType" name="v4PSType" namespace="financetypes:defn:v4" />
            </annox:annotate>
        </jaxb:bindings>

        <jaxb:bindings node="//xs:complexType[@name='PSTypev5']">
            <annox:annotate target = "class">
                <annox:annotate annox:class="javax.xml.bind.annotation.XmlType" name="v5PSType" namespace="financetypes:defn:v5" />
            </annox:annotate>
        </jaxb:bindings>

        <jaxb:bindings node="//xs:element[@name='root']//xs:complexType//xs:all//xs:element[@name='v5PSType']">
            <annox:annotate target = "field">
                <annox:annotate annox:class="javax.xml.bind.annotation.XmlElement" name="PS" namespace="financetypes:defn:v5" />
            </annox:annotate>
        </jaxb:bindings>

        <jaxb:bindings node="//xs:element[@name='root']//xs:complexType//xs:all//xs:element[@name='v4PSType']">
            <annox:annotate target = "field">
                <annox:annotate annox:class="javax.xml.bind.annotation.XmlElement" name="PS" namespace="financetypes:defn:v4" />
            </annox:annotate>
        </jaxb:bindings>
    </jaxb:bindings>
</jaxb:bindings>

然后你最终会得到我回答中的类(class)。

关于java - 如何修复 Jaxb 的 xmlMapper "Multiple fields representing property "PS""问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55037312/

相关文章:

javascript - 如何在没有 ID (Java) 的 Selenium 中单击 Javascript 按钮?

java - 使用 XMLSchema : Best Practices? (Java) 配置解析代码中的 XML 验证

java - JSON 序列化时 jsonrpc4j null

java - 使用列表反序列化 JSON 包装对象会返回 null 属性

java - 使用ehcache来处理文件处理

java - 如何将永久 CLASSPATH 添加到 Mac OS El Capitan 上的终端?

java - 如何判断两个String是否相等(大写和小写)-Java

xml - 可选择使用 xsl 样式表

android - Android Studio 上的 PreferenceScreen

java - ObjectMapper 附加文​​件 JSON