我在peek文档中找不到任何XMLStreamReader或unread函数。为了解析一个子元素列表(例如,HTML列表中的子元素),获得至少一个标记的首选方法是什么?
<ul>
<li>
<li>
</ul>当我为ul和li创建一个具有解析函数的递归解析器时,li解析函数必须在找到ul的结束标记时终止,但它不能使用它,因为ul解析函数需要它成功。
我习惯于用peek或unread来解决这样的问题,但它们似乎是缺失的。解决这个问题的首选Java方法是什么?
更新:我实现了解析器,而没有使用XMLStreamReader。
发布于 2012-09-24 08:26:58
似乎没有一种直接的方法可以做到这一点。您可以使用XMLEventReader来完成相同的功能吗?
发布于 2012-10-03 17:27:34
有一种实现递归解析器的通用方法,通过预读下一个令牌,存储它,并对其进行测试,从而避免了对unread或peek的需求:
<li>和</ul>)对其进行测试。实际上,你已经看过前面了。
第一版的巨龙编译器书有一个很好的例子,在他们的早期概述章节,在C(他们使用Java在第二版,但它不必要地夸大,IMHO -C风格在Java中工作得很好)。
我将尝试从我自己的源代码中提取一个示例,但是我的代码被分隔成一个库层,其中包含处理更容易使用的方法的方法。我将尝试将它们结合起来,以提供一个明确的示例,但它可能不会独立运行。把它想象成伪代码,来说明这个想法,你需要填补这些空白。
XMLStreamReader in;
int token;
String localname;
public void parse() {
next();
if (token==START_ELEMENT && localname.equals("ul")) ul();
}
void ul() {
next(); // assume we are called when a <ul> is seen, so we consume it
while (true) { // loops for list
if (token==START_ELEMENT && localname.equals("li")) li(); // ifs for choice
else if (token==START_ELEMENT && localname.equals("sometag")) sometag();
else break;
}
if (token==END_ELEMENT && localname.equals("ul")) next();
else throw new RuntimeException("expected </ul>");
// <li> or <sometag> would also be acceptable
}
void li() {
next();
...
}
void next() {
token = in.next(); // consume the token means to set up the next one
localname = in.getLocalName();
}如果您创建一个图层库来处理重复的内容,我发现使用起来要容易得多,例如:
boolean startTag(String name)只返回truevoid requireStartTag(String name)将消耗,否则抛出异常但我认为这个例子更清晰,保持所有文字。
还有其他问题,如跳过非元素标记(如注释、PI等);跟踪您所处的行以寻找更有帮助的异常,等等。
https://stackoverflow.com/questions/12561181
复制相似问题