难以在Java中解组XML

时间:2017-08-29 01:55:55

标签: java xml exception unmarshalling javax

这是我收到的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()。问题是没有与此位相关联的类型,因此它以ObjectNSImpl的形式返回。我不控制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 unmarshalling方面我很弱。

1 个答案:

答案 0 :(得分:1)

您正在忽略响应中的XML命名空间,如xmlns属性中所定义。有关命名空间和定义命名空间的属性的完整说明,请参阅https://www.w3.org/TR/xml-names/

用于描述具有名称空间的XML名称的标准表示法是{ namespace-uri } local-name 。因此异常实际上告诉您,您的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的位置作为参数来使您的任务变得更加容易。所有编组都将由生成的服务和端口类隐式处理。