我正在使用一些第三方REST Web服务。我正在做的是使用SAX解析器解析它的响应。作为回应,我有一组<section>
标记,每个标记都包含一个<text>
标记以及更多标记。本文基本上是对产品的评论,因此用户可以在其中键入任何他喜欢的内容(或者在ws-provider的网站上允许的内容)。
我在一个地方遇到了解析此<text>
标记的问题。仅在一个案例中得到30条评论的答案就会表现得很奇怪。
这是一块正在解析的xml
<text>Prachtige vormgeving. RVS/Zwart, zoals afbeelding hierbij. Even de handleiding doorlezen en daarna zeer handig in gebruik. Koffie is heerlijk. Heet water voor thee of zelfs kopje Nescafé. Cups zijn eur 0,31/0,33 per stuk. Via de site kan je een startersaanbieding met presentatiekist bestellen.<br/>Sommige onderdelen zijn natuurlijk heet, pas op met kinderhandjes. Kortom: zeer tevreden!!<br/> </text>
我已经实施了org.xml.sax.helpers.DefaultHandler
我做了所有的事情。奇怪的是为什么我的public void characters(char[] ch, int start, int length)
方法被调用两次以上的xml。我调试并发现第一次使用包含文本char[] ch
的{{1}}和第二次使用空字符串调用它,导致覆盖真实文本,因此我没有审阅文本对于这些特定的审查项目。这是为什么?这是一个错误吗?
我做了一个额外的检查,如果我已经有了文本,那么下次就忽略文本分配。所以它仍然可以正常工作。
另外我已经想到,当第二次调用时,qName是一个空字符串,而第一次是'TEXT'。 (它在"Prachtige vormgeving...."
方法中)。我的java是1.5_06,在OC4J 10.1.3.5上部署我的应用程序。
再次,问题是:这是一个错误吗?或者是正常行为,我只是错过了一些关于SAX解析的知识?
答案 0 :(得分:3)
您应该累积characters
中收到的字符。您描述的行为符合SAX specification。由解析器决定何时以及如何调用characters
方法:
Parser将调用此方法来报告每个字符块 数据。 SAX解析器可以在单个中返回所有连续的字符数据 大块,或者他们可能将它分成几个块;但是,所有的 任何单个事件中的字符必须来自同一个外部实体 以便定位器提供有用的信息。
这样的事情可能有所帮助(未选中):
class MyHandler extends DefaultHandler {
StringBuilder chars = new StringBuilder();
...
private void flushCharacters() {
char [] data = chars.toString().toCharArray();
// use data as you want or use just chars.toString()
chars.delete(0, chars.length());
}
@Override
public void characters(char [] data, int offset, int length) {
chars.append(char, offset, length);
}
...
// call flushCharacters in
// startElement/endElement/processingInstruction and wherever you want
}