Java SAX DefaultHandler解析使用多个同名标记获取标记值

Java SAX DefaultHandler解析使用多个同名标记获取标记值,java,xml-parsing,sax,Java,Xml Parsing,Sax,我有以下输入XML: <REQUEST> <ELEMENT>element inside request</ELEMENT> <NUMBER>250</NUMBER> <LIST> <ELEMENT>element inside list</ELEMENT> <LETTER>A</LETTER> </

我有以下输入XML:

<REQUEST>
    <ELEMENT>element inside request</ELEMENT>
    <NUMBER>250</NUMBER>
    <LIST>
          <ELEMENT>element inside list</ELEMENT>
          <LETTER>A</LETTER>
    </LIST>
    <OTHER1>other 1</OTHER1>
</REQUEST>
我有这个逻辑来获取元素值请求是一个HttpServletRequest:

ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buf = new byte[1024];
int n = 0;
while ((n = request.getInputStream().read(buf)) >= 0) {
    baos.write(buf, 0, n);
}
byte[] content = baos.toByteArray();
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser saxParser = factory.newSAXParser();
MyHandler handler = new MyHandler();
saxParser.parse(new ByteArrayInputStream(content), handler);
return handler.getElement();
当我发送上面的XML时,我们得到REQUEST->LIST->ELEMENT中的值,因此我得到字符串:

列表中的元素

但是我想把字符串放在第一个元素标记里面

请求中的元素


我需要完成MyHandler类中的代码,以获取REQUEST->ELEMENT中的元素值,而不获取其他元素。

您需要跟踪XML中的完整位置

注意-这是完全未经测试的代码

public class MyHandler extends DefaultHandler {

    // Use a DEQUE to track the current position inthe xml.
    private Deque<String> position = new ArrayDeque<>();
    // My data.
    private StringBuilder data = new StringBuilder();

    private String element = null;

    @Override
    public void characters(char[] ch, int start, int length) throws SAXException {
        if (match()) {
            // Append to my buffer.
            data.append(ch, start, length);
        }
    }

    @Override
    public void endElement(String uri, String localName, String qName) throws SAXException {
        // Ending a tag - pop it from end.
        position.removeLast();
    }

    @Override
    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
        // Starting a tag - push it at the end.
        position.addLast(qName);
    }

    public String getElement() {
        return this.element;
    }

    // Specifically looking for the REQUEST.ELEMENT - not the REQUEST.LIST.ELEMENT
    private final String[] lookingFor = {"REQUEST", "ELEMENT"};

    private boolean match() {
        // Must be that deep.
        if (position.size() == lookingFor.length) {
            // Must match.
            Iterator<String> match = position.iterator();
            for (int i = 0; i < lookingFor.length; i++) {
                // Match?
                if (!match.next().equals(lookingFor[i])) {
                    return false;
                }
            }
        } else {
            // Wrong depth.
            return false;
        }
        // No mismatch -> match!
        return true;
    }

}
另外,作为旁白,在调用字符时应该始终追加

public class MyHandler extends DefaultHandler {

    // Use a DEQUE to track the current position inthe xml.
    private Deque<String> position = new ArrayDeque<>();
    // My data.
    private StringBuilder data = new StringBuilder();

    private String element = null;

    @Override
    public void characters(char[] ch, int start, int length) throws SAXException {
        if (match()) {
            // Append to my buffer.
            data.append(ch, start, length);
        }
    }

    @Override
    public void endElement(String uri, String localName, String qName) throws SAXException {
        // Ending a tag - pop it from end.
        position.removeLast();
    }

    @Override
    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
        // Starting a tag - push it at the end.
        position.addLast(qName);
    }

    public String getElement() {
        return this.element;
    }

    // Specifically looking for the REQUEST.ELEMENT - not the REQUEST.LIST.ELEMENT
    private final String[] lookingFor = {"REQUEST", "ELEMENT"};

    private boolean match() {
        // Must be that deep.
        if (position.size() == lookingFor.length) {
            // Must match.
            Iterator<String> match = position.iterator();
            for (int i = 0; i < lookingFor.length; i++) {
                // Match?
                if (!match.next().equals(lookingFor[i])) {
                    return false;
                }
            }
        } else {
            // Wrong depth.
            return false;
        }
        // No mismatch -> match!
        return true;
    }

}