gpt4 book ai didi

java - 如何获得 XMLStreamReader 的前瞻性?

转载 作者:行者123 更新时间:2023-12-02 00:12:12 24 4
gpt4 key购买 nike

我在XMLStreamReader中找不到任何peekunread功能文档。例如,为了解析 HTML 列表中的子元素列表,获得至少一个标记前瞻的首选方法是什么?

<ul>
<li>
<li>
</ul>

当我使用 ulli 的解析函数创建递归体面解析器时,li 解析函数必须在找到结束时终止ul 的标签,但不能消耗它,因为 ul 解析函数需要它才能成功。

我习惯用peekunread来解决此类问题,但它们似乎丢失了。解决这个问题的首选 Java 方法是什么?

更新:我使用 XMLStreamReader 实现了没有前瞻的解析器。

最佳答案

有一种常见的实现递归解析器的方法可以避免 unread 的需要。或peek ,通过预读取下一个标记、存储它并对其进行测试:

  • 当您读入 token 时,会将其存储在(全局)变量中。
  • 然后您只需使用您要查找的所有标记(例如 <li></ul> )对其进行测试
  • 找到正确的方法后,您可以调用处理该问题的方法(或继续)
  • (读取下一个标记,“消耗”匹配的标记)

实际上,您已经看到了前方。

Dragon 编译器书的第一版在其早期概述章节中以 C 语言提供了一个很好的示例(他们在第二版中使用了 Java,但没有必要夸大其词,恕我直言 - 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)如果匹配则返回 true
  • void requireStartTag(String name)如果匹配则消耗,否则抛出异常

但我认为这个例子更清楚,保留所有字面意义。

还有其他问题,例如跳过非元素标记(例如评论、PI 等);跟踪您所在的线路以获取更多有用的异常(exception)情况等。

关于java - 如何获得 XMLStreamReader 的前瞻性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12561181/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com