在 Java 中解组 XML 时遇到问题
Having trouble Unmarshalling XML in Java
这是我收到的xml
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<soap-env:Envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/">
<soap-env:Header/>
<soap-env:Body RequestId="1503948112779" Transaction="HotelResNotifRS">
<OTA_HotelResNotifRS xmlns="http://www.opentravel.org/OTA/2003/05" TimeStamp="2017-08-28T19:21:54+00:00" Version="1.003">
<Errors>
<Error Code="450" Language="en-us" ShortText="Unable to process " Status="NotProcessed" Type="3">Discrepancy between ResGuests and GuestCounts</Error>
</Errors>
</OTA_HotelResNotifRS>
</soap-env:Body>
</soap-env:Envelope>
这会伪解编组到 OTAHotelResNotifRS 对象中,您可以在该对象上获取 .getErrors()。问题在于没有与该位相关联的类型,因此它以 ElementNSImpl 形式的对象形式返回。我不控制 OTAHotelResNotifRS 对象,所以我最好的选择是将 .getErrors() 对象解组到我自己的 pojo 中。这是我的尝试。
@XmlRootElement(name = "Errors")
@XmlAccessorType(XmlAccessType.FIELD)
public class CustomErrorsType {
@XmlAnyElement(lax = true)
private String[] errors;
public String[] getErrors() {
return errors;
}
}
这是用于尝试将其解组到我的 CustomErrorsType 对象中的代码
Object errorsType = otaHotelResNotifRS.getErrors();
JAXBContext context = JAXBContext.newInstance(CustomErrorsType.class);
Unmarshaller unmarshaller = context.createUnmarshaller();
CustomErrorsType customErrorsType = (CustomErrorsType)unmarshaller.unmarshal((Node)errorsType);
调用unmarshal时抛出如下异常
javax.xml.bind.UnmarshalException: unexpected element (uri:"http://www.opentravel.org/OTA/2003/05", local:"Errors"). Expected elements are <{}Errors>
有什么想法吗?在 xml 解组方面我很弱。
您忽略了响应中的 XML 命名空间,如 xmlns
属性中所定义。有关命名空间和定义它们的属性的完整说明,请参阅 https://www.w3.org/TR/xml-names/。
描述一个 XML 名称及其命名空间的标准符号是 {
namespace-uri}
local -姓名。因此,异常实际上是在告诉您,您的 CustomErrorsType 需要一个具有本地名称 Errors
和空命名空间 ({}
) 的元素,但它遇到了一个具有本地名称 Errors
的元素,并且命名空间 http://www.opentravel.org/OTA/2003/05
.
尝试改变这个:
@XmlRootElement(name = "Errors")
对此:
@XmlRootElement(name = "Errors", namespace = "http://www.opentravel.org/OTA/2003/05")
附带说明一下,如果您有权访问定义 SOAP 服务的 WSDL,则可以通过调用标准 JDK 工具 wsimport 并将 WSDL 的位置作为一个论点。所有编组将由生成的服务和端口隐式处理类。
这是我收到的xml
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<soap-env:Envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/">
<soap-env:Header/>
<soap-env:Body RequestId="1503948112779" Transaction="HotelResNotifRS">
<OTA_HotelResNotifRS xmlns="http://www.opentravel.org/OTA/2003/05" TimeStamp="2017-08-28T19:21:54+00:00" Version="1.003">
<Errors>
<Error Code="450" Language="en-us" ShortText="Unable to process " Status="NotProcessed" Type="3">Discrepancy between ResGuests and GuestCounts</Error>
</Errors>
</OTA_HotelResNotifRS>
</soap-env:Body>
</soap-env:Envelope>
这会伪解编组到 OTAHotelResNotifRS 对象中,您可以在该对象上获取 .getErrors()。问题在于没有与该位相关联的类型,因此它以 ElementNSImpl 形式的对象形式返回。我不控制 OTAHotelResNotifRS 对象,所以我最好的选择是将 .getErrors() 对象解组到我自己的 pojo 中。这是我的尝试。
@XmlRootElement(name = "Errors")
@XmlAccessorType(XmlAccessType.FIELD)
public class CustomErrorsType {
@XmlAnyElement(lax = true)
private String[] errors;
public String[] getErrors() {
return errors;
}
}
这是用于尝试将其解组到我的 CustomErrorsType 对象中的代码
Object errorsType = otaHotelResNotifRS.getErrors();
JAXBContext context = JAXBContext.newInstance(CustomErrorsType.class);
Unmarshaller unmarshaller = context.createUnmarshaller();
CustomErrorsType customErrorsType = (CustomErrorsType)unmarshaller.unmarshal((Node)errorsType);
调用unmarshal时抛出如下异常
javax.xml.bind.UnmarshalException: unexpected element (uri:"http://www.opentravel.org/OTA/2003/05", local:"Errors"). Expected elements are <{}Errors>
有什么想法吗?在 xml 解组方面我很弱。
您忽略了响应中的 XML 命名空间,如 xmlns
属性中所定义。有关命名空间和定义它们的属性的完整说明,请参阅 https://www.w3.org/TR/xml-names/。
描述一个 XML 名称及其命名空间的标准符号是 {
namespace-uri}
local -姓名。因此,异常实际上是在告诉您,您的 CustomErrorsType 需要一个具有本地名称 Errors
和空命名空间 ({}
) 的元素,但它遇到了一个具有本地名称 Errors
的元素,并且命名空间 http://www.opentravel.org/OTA/2003/05
.
尝试改变这个:
@XmlRootElement(name = "Errors")
对此:
@XmlRootElement(name = "Errors", namespace = "http://www.opentravel.org/OTA/2003/05")
附带说明一下,如果您有权访问定义 SOAP 服务的 WSDL,则可以通过调用标准 JDK 工具 wsimport 并将 WSDL 的位置作为一个论点。所有编组将由生成的服务和端口隐式处理类。