【发布时间】:2016-11-09 21:45:33
【问题描述】:
我已经有好几年没有调试 JAXB 解组了。我看到了这样一种情况,即正确解析了具有名称空间的有效 XML 文档,但是当代码将文档解组为对象时,对象中的某些属性未设置,使它们为空。我可以单步执行代码,但是一旦进入 jaxb 解组,就很难理解它在做什么。它似乎直接在 JAXB 类的实例上设置实例变量(设置为 FIELD),因此我无法在设置器中设置断点以查看它何时(或是否)设置特定属性。
我可以使用一些提示来了解如何对解组过程进行更多诊断,以查看可能出现的问题。
被解析的 XML 文档相对简单。这是一个 SOAP 信封,解组是在主体的第一个孩子上完成的。
所讨论的子元素指定了两个命名空间,一个是周围元素的默认命名空间,另一个是在某些子元素中引用的非默认命名空间。实际上,来自非默认命名空间的所有元素最终在未编组的结果中为 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>
【问题讨论】: