-->

Skip invalid xml element with XmlStreamReader

2019-09-17 14:56发布

问题:

I want to parse my xml:

<?xml version="1.0" encoding="UTF-8" ?>
<REPLY SERVICENAME="ServerWrapper">
    <ROWSET name="ServiceName">
        <ROW num="1">
            <AMOUNT_TOTAL>26865</AMOUNT_TOTAL>
            <REQUESTED_SEARCH_VALUE>eur</REQUESTED_SEARCH_VALUE>
            <SELECTED_ID>ABC,XYZ</SELECTED_ID>
            <AMOUNT>10</AMOUNT>
            <ABC,XYZ.AMOUNT>26865</ABC,XYZ.AMOUNT>
            <ROWSET name="ServiceName.DATA">
                <ROW num="1">
                </ROW>
                ...
             </ROWSET>
        </ROW>
    </ROWSET>
</REPLY>

In this XML, I need to skip an invalid element <ABC,XYZ.AMOUNT>26865</ABC,XYZ.AMOUNT>. I'm using XMLStreamReader class for parsing the xml.

My parser class:

public Object decode(String xml) {
    XMLInputFactory xmlFactory = null;
    String textValue = "";
    xmlFactory = XMLInputFactory.newInstance();
    try {
        xmlFactory.setProperty(XMLInputFactory.IS_REPLACING_ENTITY_REFERENCES, Boolean.TRUE);
        xmlFactory.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, Boolean.FALSE);
        xmlFactory.setProperty(XMLInputFactory.IS_COALESCING, Boolean.TRUE);

        XMLStreamReader xmlReader;
        InputStream stream = new ByteArrayInputStream(xml.getBytes());

        xmlReader = xmlFactory.createXMLStreamReader(stream);

        while (xmlReader.hasNext()) {
            int eventType;
            try {
                eventType = xmlReader.next();
            } catch (XMLStreamException ex) {
                continue;
            }

            switch (eventType) {
                case XMLEvent.START_ELEMENT:
                    treePath.append("/").append(xmlReader.getLocalName());
                    attribute(xmlReader);
                    break;
                case XMLEvent.END_ELEMENT:
                    endElement(xmlReader, textValue);
                    break;
                case XMLEvent.END_DOCUMENT:
                    endDocument();
                    break;
                case XMLEvent.CHARACTERS:
                    textValue = xmlReader.getText();
                    break;
                default:
                    break;
            }
        }

    } catch (XMLStreamException ex) {
        LOGGER.error("Error on parsing data", ex);
        ex.printStackTrace();
    }

    LOGGER.info("Decode finished on[{}]", Calendar.getInstance().getTime());

    Object[] response = new Object[1];        
    response[0] = responseList;
    return response;
}

But while parsing I'm getting an exception:

javax.xml.stream.XMLStreamException: ParseError at [row,col]:[2,237]
Message: Element type "ABC" must be followed by either attribute specifications, ">" or "/>".
at com.sun.org.apache.xerces.internal.impl.XMLStreamReaderImpl.next(XMLStreamReaderImpl.java:601)

Can anyone help me to fix this issue ?