从XMLStreamReader解组未知标记时回退到JAXBElement

时间:2018-12-19 10:26:58

标签: java jaxb sax

我需要使用SAX解析巨大的xml,并使用jaxb解组单个已知元素。 如果我用List解组具有@XmlAnyElement(lax=true)的根bean,一切都很好:已知标签被转换为JAXBContext已知的类,未知标签成为DOM Element的实例。

但是,如果我跳过根元素并取消编组单个对象,则第一个未知标记会导致unexpected element异常。如果我使用显式unmarshal()调用Object.class,那么即使是已知标签也会变成JAXBElement

输出:

<Root>
    <Header/>
    <Product/>
    <Product/>
    <Product/>
    <Product/>
    <Product/>
    <Unknown/>
</Root>


class com.common.config.Problem$Header
class com.common.config.Problem$Product
class com.common.config.Problem$Product
class com.common.config.Problem$Product
class com.common.config.Problem$Product
class com.common.config.Problem$Product
Exception in thread "main" javax.xml.bind.UnmarshalException
 - with linked exception:
[com.sun.istack.internal.SAXParseException2; lineNumber: 8; columnNumber: 15; unexpected element (uri:"", local:"Unknown"). Expected elements are <{}Header>,<{}Product>]

我希望它回退到JAXBElementElement。可能吗?代码:

    import java.io.StringReader;

    import javax.xml.bind.JAXBContext;
    import javax.xml.bind.Unmarshaller;
    import javax.xml.bind.annotation.XmlRootElement;
    import javax.xml.stream.XMLInputFactory;
    import javax.xml.stream.XMLStreamReader;

    //@XmlRootElement(name = "Root")
    //@XmlAccessorType(XmlAccessType.FIELD)
    public class Problem {

        //@XmlAnyElement(lax = true)
        //protected final List<Object> accounts = new ArrayList<Object>();

        public static void main(final String[] args) throws Exception {

            System.err.println(XML);
            final JAXBContext jaxbContext = JAXBContext.newInstance(Header.class, Product.class);
            final Unmarshaller unm = jaxbContext.createUnmarshaller();

            XMLStreamReader reader = XMLInputFactory.newInstance().createXMLStreamReader(new StringReader(XML));
            boolean skipNext = false;
            int event = 0;
            boolean rootElSkipped = false;
            while (reader.hasNext()) {
                if (!skipNext) {
                    event = reader.next();
                }
                if (event == XMLStreamReader.START_ELEMENT) {
                    if (rootElSkipped) {
                        Object obj = unm.unmarshal(reader);
                        System.err.println(obj.getClass());
                    } else {
                    }
                    rootElSkipped = true;
                }
            }

        }

        static final String XML = "<Root>\r\n" + "    <Header/>\r\n" + "    <Product/>\r\n" + "    <Product/>\r\n"
                + "    <Product/>\r\n" + "    <Product/>\r\n" + "    <Product/>\r\n" + "    <Unknown/>\r\n" + "</Root>\r\n"
                + "\r\n" + "";

        @XmlRootElement(name = "Header")
        public static class Header {

        }

        @XmlRootElement(name = "Product")
        public static class Product {

        }

    }

0 个答案:

没有答案