当文档

时间:2015-09-10 05:39:10

标签: java sax saxparser

我使用SAX解析器从大型XML文件中读取一些元素。下面是我为此目的使用的示例XML和SAX解析器代码。

<someOtherElement>231</someOtherElement>
<someMoreOtherElement>1233.00213</someMoreOtherElement>
...
<elementToRead1>31.0.1</elementToRead1>
<elementToRead2>ABCD-XYZ-1.0</elementToRead2>

解析器代码:

public class MyHandler extends DefaultHandler {

    private String elementToRead1

    private Boolean flag1 = false;

    private String elementToRead2

    private Boolean flag2 = false;

    public void readValues(final String xmlString) throws XMLParseException {
        SAXXMLParser.parseString(xmlString, this);
    }

    @Override
    public void startElement(final String uri, final String localName, final String qName, final Attributes attributes) {

        if (""elementToRead1"".equals(qName)) {
            flag1 = true;
        }

        if (""elementToRead2"".equals(qName)) {
            flag2 = true;
        }
    }

    @Override
    public void characters(final char ch[], final int start, final int length) {
        if (flag1) {
            elementToRead1 = new String(ch.clone(), start, length);
            flag1 = false;
        }

        if (flag2) {
            elementToRead2 = new String(ch.clone(), start, length);
            flag2 = false;
        }
    }

}

一切正常,我正在使用此代码获得正确的值。但是在测试时,我尝试将XML中的一个元素的值更改为非常长的东西,因为我需要在解析器中读取的元素之一开始错误地解决它。 假设问题XML是:

 <someOtherElement>231</someOtherElement>
<someMoreOtherElement>9999999999999999999999999999999999999999999999999999999999999991233.00213</someMoreOtherElement>
...
<elementToRead1>31.0.1</elementToRead1>
<elementToRead1>ABCD-XYZ-1.0</elementToRead2>

使用这种XML,元素的值总是如下所示:

elementToRead1 - 31.0.1

elementToRead2 - ABCD-XYZ-1

我不知道为什么第二个元素读错了。我已经尝试使用调试点和所有内容,我可以确认在任何地方都没有抛出异常。对于此问题XML,仅读取第二个元素的值。

1 个答案:

答案 0 :(得分:6)

我有一个类似的问题,它是由值多次调用的字符方法引起的。您需要使用StringBuilder并附加字符以获取正确的值,然后在endElement中设置值并重置构建器。

它应该有用。

@Override
public void startElement(final String uri, final String localName, final String qName, final Attributes attributes) {
    stringBuffer.setLength(0);

    if ("elementToRead1".equals(qName)) {
        flag1 = true;
    }
}

@Override
public void characters(char ch[], int start, int length) {
    stringBuffer.append(new String(ch, start, length));
}

@Override
public void endElement(String namespaceURI, String localName, String qName) throws SAXException {
    String result = stringBuffer.toString();

    if (flag1) {
        elementToRead1 = result;
        flag1 = false;
    }
}

来自docs

  

SAX解析器可以在一个块中返回所有连续的字符数据,或者它们可以将它分成几个块;但是,任何单个事件中的所有字符都必须来自同一个外部实体,以便Locator提供有用的信息。