我使用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,仅读取第二个元素的值。
答案 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提供有用的信息。