有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java JAXB解组器正在跳过具有其他命名空间的元素

我调试JAXB解组已经好几年了。我看到了一种情况,即正确解析了具有名称空间的有效XML文档,但当代码将文档解组为对象时,对象中的某些属性没有设置,从而使它们为空。我可以逐步完成代码,但一旦它进入jaxb解组,就很难理解它在做什么。它似乎直接在JAXB类的实例上设置实例变量(设置为字段),因此我无法在setters中设置断点以查看它何时(或是否)设置了特定属性

我可以使用一些提示来了解如何对解组过程进行更多诊断,以了解可能出现的错误

正在解析的XML文档相对简单。这是一个肥皂信封,拆封是在身体的第一个孩子身上完成的

所讨论的子元素指定了两个名称空间,一个是周围元素的默认名称空间,另一个是在某些子元素中引用的非默认名称空间。实际上,来自非默认名称空间的所有元素在解组结果中都以null结尾。我想这是一条重要的线索,但我不能从中看出什么是错的

通过一些省略,SOAP主体的第一个子元素如下所示:

<validationResponse xmlns="http://.../ValidationResponse.xsd" xmlns:dm="http://.../DataModel.xsd">
<indicator>true</indicator>
<MatchedAddressResult>
<AddressMatchResult>
<dm:Address>
<dm:Street>
<dm:streetNumber>10000</dm:streetNumber>
<dm:streetName>ELM</dm:streetName>
<dm:streetType>ST</dm:streetType>
</dm:Street>
<dm:Unit>
<dm:type>APT</dm:type>
<dm:value>2033</dm:value>
</dm:Unit>
<dm:city>NOWHERE</dm:city>
<dm:state>TX</dm:state>
<dm:Zip>
<dm:zipCode>11111</dm:zipCode>
<dm:zipCodeExtension>2740</dm:zipCodeExtension>
</dm:Zip>
<dm:county>NOWHERE</dm:county>
</dm:Address>
<dm:cassAddress>
<dm:addressLine>10000 ELM ST APT 2033</dm:addressLine>
<dm:addressLine>NOWHERE TX  11111-2740</dm:addressLine>
</dm:cassAddress>
<dm:addressMatchCode>4S80</dm:addressMatchCode>
<dm:isAddressException>false</dm:isAddressException>
</AddressMatchResult>
</MatchedAddressResult>
<Response>
<dm:code>0</dm:code>
<dm:description>Success</dm:description>
</Response>
</validationResponse>

JAXB类的顶部如下所示:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name="ValidateAddressResponseInfo", propOrder={"matchedAddressIndicator", "matchedAddressResult", "response"})
public class ValidationResponseInfo implements Serializable
{
  protected boolean matchedAddressIndicator;
  @XmlElement(name="MatchedAddressResult")
  protected MatchedAddressResult matchedAddressResult;
  @XmlElement(name="Response", required=true)
  protected ResponseInfo response;

  @XmlAccessorType(XmlAccessType.FIELD)
  @XmlType(name="", propOrder={"exactMatchLocation", "alternativeLocation", "addressMatchResult"})
  public static class MatchedAddressResult
    implements Serializable
  {
    @XmlElement(name="ExactMatchLocation")
    protected ExactMatchLocation exactMatchLocation;

    @XmlElement(name="AlternativeLocation")
    protected AlternativeLocation alternativeLocation;

    @XmlElement(name="AddressMatchResult")
    protected List<AddressValidationResultInfo> addressMatchResult;

同样,映射到“dm”前缀的所有字段最终都为空。不知何故,解组并没有映射这些属性

更新

下面是有关元素的模式摘录

  <xs:complexType name='AddressValidationResultInfo'>
    <xs:sequence>
      <xs:element name='Address'>
        <xs:complexType>
          <xs:complexContent>
            <xs:extension base='AddressUnrestrictedInfo'>
              <xs:sequence>
                <xs:element name='addressType' type='AddressTypeInfo' minOccurs='0'/>
              </xs:sequence>
            </xs:extension>
          </xs:complexContent>
        </xs:complexType>
      </xs:element>
      <xs:element name='cassAddress' type='CassAddressInfo' minOccurs='0'/>
      <xs:element name='addressMatchCode' type='xs:string' minOccurs='0'>
      </xs:element>
      <xs:element name='addressMatchDescription' type='xs:string' minOccurs='0'>
      </xs:element>
      <xs:element name='addressId' type='FiberServiceAddressIdInfo' minOccurs='0'>
      </xs:element>
      <xs:element name='exchangeCode' type='FiberServiceExchangeCodeInfo' minOccurs='0'>
      </xs:element>
      <xs:element name='isAddressException' type='xs:boolean'>
      </xs:element>
      <xs:element name='addressExceptionCode' type='xs:string' minOccurs='0'>
      </xs:element>
      <xs:element name='addressExceptionDescription' type='xs:string' minOccurs='0'>
      </xs:element>
      <xs:element name='crossBoundaryState' type='CrossBoundaryStateInfo' minOccurs='0'>
      </xs:element>
      <xs:element name='confidence' type='xs:long' minOccurs='0'>
      </xs:element>
    </xs:sequence>
  </xs:complexType>

  <xs:complexType name='AddressUnrestrictedInfo'>
    <xs:sequence>
      <xs:element name='attention' type='xs:string' minOccurs='0'/>
      <xs:element name='addressLine1' type='AddressLineInfo' minOccurs='0'>
      </xs:element>
      <xs:element name='addressLine2' type='AddressLineInfo' minOccurs='0'>
      </xs:element>
      <xs:element name='Street' type='AddressStreetUnrestrictedInfo' minOccurs='0'/>
      <xs:element name='Elevation' type='AddressAttributeInfo' minOccurs='0'>
      </xs:element>
      <xs:element name='Structure' type='AddressAttributeInfo' minOccurs='0'>
      </xs:element>
      <xs:element name='Unit' type='AddressAttributeInfo' minOccurs='0'>
      </xs:element>
      <xs:element name='postOfficeBox' type='xs:string' minOccurs='0'/>
      <xs:element name='RuralRoute' minOccurs='0'>
        <xs:complexType>
          <xs:sequence>
            <xs:element name='ruralRouteCenterNumber' type='xs:string'/>
            <xs:element name='ruralRouteBoxNumber' type='xs:string'/>
          </xs:sequence>
        </xs:complexType>
      </xs:element>
      <xs:element name='city' type='AddressCityInfo' minOccurs='0'/>
      <xs:element name='state' type='AddressStateInfo' minOccurs='0'/>
      <xs:element name='Zip' type='AddressZipInfo' minOccurs='0'/>
      <xs:element name='country' type='xs:string' minOccurs='0'/>
      <xs:element name='county' type='xs:string' minOccurs='0'>
      </xs:element>
      <xs:element name='countyCode' minOccurs='0'>
        <xs:simpleType>
          <xs:restriction base='xs:string'>
            <xs:maxLength value='3'/>
          </xs:restriction>
        </xs:simpleType>
      </xs:element>
      <xs:element name='urbanizationCode' type='AddressUrbanizationInfo' minOccurs='0'/>
    </xs:sequence>
  </xs:complexType>

  <xs:complexType name='AddressStreetUnrestrictedInfo'>
    <xs:sequence>
      <xs:element name='streetNumberPrefix' type='xs:string' minOccurs='0'>
      </xs:element>
      <xs:element name='streetNumber' type='xs:string' minOccurs='0'>
      </xs:element>
      <xs:element name='streetNumberSuffix' type='xs:string' minOccurs='0'>
      </xs:element>
      <xs:element name='streetDirection' type='xs:string' minOccurs='0'>
      </xs:element>
      <xs:element name='streetName' type='xs:string' minOccurs='0'/>
      <xs:element name='streetType' type='xs:string' minOccurs='0'>
      </xs:element>
      <xs:element name='streetTrailingDirection' type='xs:string' minOccurs='0'>
      </xs:element>
      <xs:element name='assignedStreetNumber' type='xs:string' minOccurs='0'>
      </xs:element>
    </xs:sequence>
  </xs:complexType>

共 (2) 个答案

  1. # 1 楼答案

    It's actually all the elements that come from the non-default namespace that end up null in the unmarshalled result. I imagine that's an important clue, but I can't tell what's wrong from that.

    事实上,很可能是这样

    在xsd中声明的soap消息中,dm prexif是否引用了xmlns? 不要犹豫显示xsd文件,这可能会有所帮助

    Again, all the fields that map to the "dm" prefix end up null. Somehow the unmarshalling isn't mapping those properties.

    它给人的印象是,在解组期间,名称空间无法识别
    名称空间在jaxb元素中不精确。所以我想它是在包信息中声明的。java文件

    是否可以检查用于具有dm prefix的元素的命名空间是否为预期的命名空间,并且该命名空间是否位于合适的包中:

    @javax.xml.bind.annotation.XmlSchema (
        namespace = "yourRealNamespaceForDn",
        elementFormDefault=javax.xml.bind.annotation.XmlNsForm.QUALIFIED
    )
    

    如果一切正常,解决问题的另一种方法是编写一个简单的单元测试,使用jaxb非序列化方法对输入中提取的xml和输出中预期创建的对象进行隔离。 通过指定名称空间属性,尝试在jaxb元素中使用名称空间声明,例如:

    @XmlType(namespace="yourNamespace", name="", propOrder={"exactMatchLocation", "alternativeLocation", "addressMatchResult"})
      public static class MatchedAddressResult ...
    
  2. # 2 楼答案

    检查XSD模式和生成的类
    问题就在这里:
    JAXB希望AddressMatchResult作为列表, 但是XML中没有任何东西可以满足它
    在XML中有一个元素

    <AddressMatchResult>
      <dm:Address>
      <dm:Street>
    

    。。。 所以对应的AddressMatchResult类必须具有直接属性,如Address、Street等。 要么更正XSD并重新生成JAXB,要么根据现有XSD更正XML