откат к JAXBElement, когда демарширует неизвестный тег из XMLStreamReader - PullRequest
0 голосов
/ 19 декабря 2018

Мне нужно проанализировать огромный xml, используя SAX, и демонтировать отдельные известные элементы, используя jaxb.Если я отменяю маршализацию корневого компонента, имеющего List с @XmlAnyElement(lax=true), все в порядке: известные теги преобразуются в классы, известные 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>]

Я хочу, чтобы он откатился до JAXBElement или Element.Является ли это возможным?код:

    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 {

        }

    }
...