簡體   English   中英

如何對XMLStreamReader有所了解?

[英]How to get look ahead for XMLStreamReader?

我在XMLStreamReader文檔中找不到任何peek或未unread函數。 例如,像HTML列表中那樣,至少需要一個令牌來解析子元素列表的首選方法是什么?

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

當我使用ulli的解析函數創建一個遞歸體面的解析器時, li解析函數必須在找到ul的結束標記時終止,但是一定不能消耗它,因為ul解析函數需要它成功。

我習慣於通過peek或未unread來解決此類問題,但它們似乎丟失了。 解決此問題的首選Java方法是什么?

更新 :我沒有使用XMLStreamReader來實現解析器。

有一種實現遞歸解析器的通用方法,它可以通過預讀下一個令牌,存儲它並進行測試來避免對unreadpeek的需求:

  • 當您讀入令牌時,會將其存儲在(全局)變量中。
  • 然后只需使用您要查找的所有令牌對其進行測試(例如<li></ul>
  • 找到正確的方法后,您將調用處理該方法的方法(或繼續執行)
  • (讀入下一個令牌,“消耗”了匹配的令牌)

實際上,您已經向前看了。

Dragon編譯器手冊的第一版在其早期概述章節的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)如果匹配則返回true
  • 如果匹配,則void requireStartTag(String name)消耗,否則拋出異常

但是我認為這個例子更加清晰。

還有其他問題,例如跳過非元素令牌(例如注釋,PI等); 跟蹤您所在的行以獲取更多有用的例外等信息。

似乎沒有做到這一點的直接方法。 您是否可以使用XMLEventReader來完成相同的功能?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM