在非映射元素上产生JAXB错误

我正试图做相反的事情:JAXB - 忽略元素

这是我想用JAXB解析XML的POJO,我想JAXB如果它没有找到一个给定元素匹配的Java属性失败。 我知道我可以做架构验证,但我宁愿不这样做。

例:

@XmlRootElement(name="Dog")
public class Dog {
    private String name;
    public String getName() {return name;}
    public String setName(String name) {this.name = name};
}

这个XML会失败:

<Dog>
<id>blah</id>
<name>Stuff</name>
</Dog>

因为没有id Java属性


您可以利用ValidationEventHandler来获取您正在查找的行为。 意外的元素被视为默认情况下被忽略的警告。 为了支持你的用例,你可以提供一个ValdidationEventHandler ,它在警告时失败(见下文)。

演示

package forum10721257;

import java.io.File;
import javax.xml.bind.*;

public class Demo {

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

        File xml = new File("src/forum10721257/input.xml");
        Unmarshaller unmarshaller = jc.createUnmarshaller();
        unmarshaller.setEventHandler(new ValidationEventHandler () {

            @Override
            public boolean handleEvent(ValidationEvent event) {
                return false;
            }

        });
        Dog dog = (Dog) unmarshaller.unmarshal(xml);
    }

}

JAXB RI异常

Exception in thread "main" javax.xml.bind.UnmarshalException: unexpected element (uri:"", local:"id"). Expected elements are <{}name>
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext.handleEvent(UnmarshallingContext.java:647)
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader.reportError(Loader.java:243)
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader.reportError(Loader.java:238)
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader.reportUnexpectedChildElement(Loader.java:105)
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader.childElement(Loader.java:90)
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.StructureLoader.childElement(StructureLoader.java:236)
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext._startElement(UnmarshallingContext.java:483)
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext.startElement(UnmarshallingContext.java:465)
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.SAXConnector.startElement(SAXConnector.java:135)
    at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.startElement(AbstractSAXParser.java:506)
    at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.scanStartElement(XMLNSDocumentScannerImpl.java:376)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(XMLDocumentFragmentScannerImpl.java:2715)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:607)
    at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(XMLNSDocumentScannerImpl.java:116)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:488)
    at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:835)
    at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:764)
    at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:123)
    at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1210)
    at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:568)
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:202)
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:174)
    at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:157)
    at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:162)
    at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:171)
    at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:189)
    at forum10721257.Demo.main(Demo.java:26)

EclipseLink JAXB(MOXy)

我们最近将此行为添加到MOXY。 您将需要使用EclipseLink 2.4.0或2.3.3。 每晚可以从以下地点获得建筑物:

  • http://www.eclipse.org/eclipselink/downloads/nightly.php

  • UPDATE

    我需要从你的问题中调整Dog类。 以下是我用过的。

    package forum10721257;
    
    import javax.xml.bind.annotation.XmlRootElement;
    
    @XmlRootElement(name="Dog")
    public class Dog {
        private String name;
        public String getName() {return name;}
        public void setName(String name) {this.name = name;}
    }
    

    我能够验证丢失的Java属性(无模式)的唯一方法是将XML解组到我的POJO,然后使用相同的POJO将其重新编码为XML并进行比较。

    下面是一个使用XMLUnit的例子,它有助于忽略顺序和空白问题。

    @Test
    public void testSerialization() throws Exception {
        XMLUnit.setIgnoreWhitespace(true);
    
        EventSearchResults r = 
                JAXB.unmarshal(getClass().getResourceAsStream("/EventSearchResults.xml"), 
                        EventSearchResults.class);
        StringWriter sw = new StringWriter();
        JAXB.marshal(r, sw);
        String expected = 
                IOUtils.toString(getClass().getResourceAsStream("/EventSearchResults.xml"), "UTF-8");
        String actual = sw.toString();
        //System.out.println(expected);
        System.out.println(actual);
        assertXMLEqual(expected, actual);
    }
    

    这并不理想,但大部分都适用于单元测试。

    链接地址: http://www.djcxy.com/p/10797.html

    上一篇: Make JAXB error on non mapped elements

    下一篇: Using Maven settings.xml properties inside Spring context