Unexpected element while unmarshalling

可紊 提交于 2019-12-13 00:29:30

问题


I have to pull information from a webservice. Here's an example of a response:

<myServices>
<myService name="A" serviceId="a" type="rest" version="1.0">
<entryPoints/>
</myService>
<myService name="B" serviceId="b" type="rest" version="1.0">
<entryPoints/>
</myService>
<myService name="C" serviceId="C" type="rest" version="1">
<entryPoints>
<entryPoint realm="external" wadl="http://myURL.com/1/app.wadl>http://myURL.com/1</entryPoint>
</entryPoints>
</myService>
<myService name="D" serviceId="d" type="rest" version="1.0">
<entryPoints/>
</myService>
</myServices>

Here's my xsd:

<?xml version="1.0" encoding="windows-1252" ?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
            xmlns="http://www.nisoars.myservices.1.com"
            targetNamespace="http://www.nisoars.myservices.1.com"
            elementFormDefault="qualified">

    <xsd:element name="myServices">
        <xsd:complexType>
            <xsd:sequence>
                <xsd:element name="myService" type="ServiceType" minOccurs="1" maxOccurs="unbounded"/>
            </xsd:sequence>
        </xsd:complexType>
    </xsd:element>  

    <xsd:complexType name="ServiceType">
        <xsd:sequence>
            <xsd:element name="entryPoints">
                <xsd:complexType>
                    <xsd:sequence>
                        <xsd:element name="entryPoint" type="EntryPointType" minOccurs="1" maxOccurs="unbounded"/>
                    </xsd:sequence>
                </xsd:complexType>
            </xsd:element>
        </xsd:sequence>
        <xsd:attribute name="name" type="xsd:string" use="required"/>
        <xsd:attribute name="serviceId" type="xsd:string" use="required"/>
        <xsd:attribute name="type" type="ServiceTypeEnum" use="required"/>
        <xsd:attribute name="version" type="xsd:string" use="required"/>
    </xsd:complexType>

    <!-- <entryPoint wadl="myWadl" realm="external">myURL</entryPoint> -->
    <xsd:complexType name="EntryPointType">
        <xsd:simpleContent>
            <xsd:extension base="xsd:anyURI">
                <xsd:attribute name="realm" type="RealmEnum" use="required"/>
                <xsd:attribute name="wadl" use="optional" type="xsd:anyURI"/> <!-- Required for REST endpoints, but not for SOAP -->
            </xsd:extension>
        </xsd:simpleContent>
    </xsd:complexType>


    <xsd:simpleType name="RealmEnum">
        <xsd:restriction base="xsd:string">
            <xsd:enumeration value="internal"/>
            <xsd:enumeration value="external"/>
        </xsd:restriction>
    </xsd:simpleType>

    <xsd:simpleType name="ServiceTypeEnum">
        <xsd:restriction base="xsd:string">
            <xsd:enumeration value="rest"/>
            <xsd:enumeration value="soap"/>
        </xsd:restriction>
    </xsd:simpleType>
</xsd:schema>

The error I'm getting is this one:

unexpected element (uri:"", local:"myServices"). Expected elements are <{http://www.nisoars.myservices.1.com}myServices>

I can't remove the namespace from the xsd because I need it for other objects. I'm using the javax.bind.xml.Unmarshaller.

Any ideas?


回答1:


Apply a Namespace

In the case where the input XML does not have a namespace you can leverage a SAX XMLFilter to apply a namespace.

import org.xml.sax.*;
import org.xml.sax.helpers.XMLFilterImpl;

public class NamespaceFilter extends XMLFilterImpl {

    private static final String NAMESPACE = "http://www.nisoars.myservices.1.com/";

    @Override
    public void endElement(String uri, String localName, String qName)
            throws SAXException {
        super.endElement(NAMESPACE, localName, qName);
    }

    @Override
    public void startElement(String uri, String localName, String qName,
            Attributes atts) throws SAXException {
        super.startElement(NAMESPACE, localName, qName, atts);
    }

}

Do the Unmarshal

The unmarshalling is done leveraging JAXB's UnmarshallerHandler as the ContentHandler

import javax.xml.bind.*;
import javax.xml.parsers.*;
import org.xml.sax.*;

public class Demo {

    public static void main(String[] args) throws Exception {
        // Create the JAXBContext
        JAXBContext jc = JAXBContext.newInstance(Customer.class);

        // Create the XMLFilter
        XMLFilter filter = new NamespaceFilter();

        // Set the parent XMLReader on the XMLFilter
        SAXParserFactory spf = SAXParserFactory.newInstance();
        SAXParser sp = spf.newSAXParser();
        XMLReader xr = sp.getXMLReader();
        filter.setParent(xr);

        // Set UnmarshallerHandler as ContentHandler on XMLFilter
        Unmarshaller unmarshaller = jc.createUnmarshaller();
        UnmarshallerHandler unmarshallerHandler = unmarshaller
                .getUnmarshallerHandler();
        filter.setContentHandler(unmarshallerHandler);

        // Parse the XML
        InputSource xml = new InputSource("input.xml");
        filter.parse(xml);
        Customer customer = (Customer) unmarshallerHandler.getResult();

        // Marshal the Customer object back to XML
        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.marshal(customer, System.out);
    }

}

For More Information

  • http://blog.bdoughan.com/2012/11/applying-namespace-during-jaxb-unmarshal.html


来源:https://stackoverflow.com/questions/25250418/unexpected-element-while-unmarshalling

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!