Would like unknown attributes to error when Jaxb unmarshalling

I'm using Jaxb to unmarshal XML into a java object. I need to know when new attributes/elements are in the XML and fail. However by default the unmarshaller is ignoring new elements/attributes.

Is there a configuration I can set to fail when new attributes/elements exist in the XML that are not specified in the POJO?

My POJO:

import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name = "ROOT")
public class Model {

    private A a;

    public A getA() {
        return a;
    }

    @XmlElement(name = "A")
    public void setA(A a) {
        this.a = a;
    }

    static class A {

        String country;

        public String getCountry() {
            return country;
        }

        @XmlAttribute(name = "Country")
        public void setCountry(String country) {
            this.country = country;
        }
    }
}

Code to unmarshal:

JAXBContext jaxbContext = JAXBContext.newInstance(Model.class);
Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();

String sample = "<ROOT>" +
                    "<A Country="0" NewAttribute="0"></A>" +
                    "<NEWELEMENT> </NEWELEMENT>" +
                "</ROOT>";
InputStream stream = new ByteArrayInputStream(sample.getBytes(StandardCharsets.UTF_8));

Object unmarshal = jaxbUnmarshaller.unmarshal(stream);

您需要调用Unmarshaller.setEventHandler()以使无效的XML内容失败。


You can block unexpected content by enabling XML Schema validation on the Unmarshaller . If you don't already have an XML Schema for your POJO, you can generate one at runtime from the JAXBContext , build a Schema object and then set it on the Unmarshaller . By default the Unmarshaller will throw an exception if the XML document isn't valid with respect to the schema.

Here's an example of how to do that:

JAXBContext jaxbContext = JAXBContext.newInstance(Model.class);

// Generate XML Schema from the JAXBContext
final List<ByteArrayOutputStream> schemaDocs = new ArrayList<ByteArrayOutputStream>();
jaxbContext.generateSchema(new SchemaOutputResolver() {
    @Override
    public Result createOutput(String namespaceUri, String suggestedFileName)
        throws IOException {
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            StreamResult sr = new StreamResult(baos);
            schemaDocs.add(baos);
            sr.setSystemId(suggestedFileName);
            return sr;
        }
    });
SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
int size = schemaDocs.size();
Source[] schemaSources = new Source[size];
for (int i = 0; i < size; ++i) {
    schemaSources[i] = new StreamSource(
        new ByteArrayInputStream(schemaDocs.get(i).toByteArray()));
}
Schema s = sf.newSchema(schemaSources);

// Set the JAXP Schema object on your Unmarshaller.
Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
jaxbUnmarshaller.setSchema(s);

String sample = "<ROOT>" +
                    "<A Country="0" NewAttribute="0"></A>" +
                    "<NEWELEMENT> </NEWELEMENT>" +
                "</ROOT>";
InputStream stream = new ByteArrayInputStream(sample.getBytes("UTF-8"));

Object unmarshal = jaxbUnmarshaller.unmarshal(stream);

Combine this with the ValidationEventHandler (set through Unmarshaller.setEventHandler() ) suggested in the previous answer if you wish to be notified about multiple errors or filter out validation errors that you want to tolerate.

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

上一篇: JAXB生成包名称的XML元素

下一篇: 当Jaxb解组时,希望未知属性出错