有執行遞歸解析器的常見方式,避免了unread
或peek
的需要,通過預讀下一個標記,存放和測試針對:
當你在一個令牌讀取
- ,你將它存儲在一個(全局)變量中。
- 那麼你只要並對它進行測試與所有你正在尋找(如
<li>
和</ul>
)
- 當你找到了合適的人,你調用處理該方法的令牌(或繼續)
- (在接下來的令牌讀取,具有「消費」相匹配的一個)
實際上,你有已經偷看領先。
龍編譯器第1版在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)
是否匹配
void requireStartTag(String name)
消耗,如果匹配,否則會引發異常
但我認爲例子是清晰的保持它的所有文字只是返回true。
還有其他問題,如跳過非元素標記(如評論,PI等);跟蹤您正在尋找哪些線路以獲取更多有用的例外情況等。
因此,是否有任何不使用SAx解析器的特定原因? –
@SomBhattacharyya:我被告知[StAX](http://docs.oracle.com/cd/E17802_01/webservices/webservices/docs/1.6/tutorial/doc/SJSXP2.html)是最現代和最好的API新的節目。使用SAX有什麼好處? – ceving
好吧,我只是順從,因爲這可以由SAX處理。它也可以用SAX完成。請使用「XMLEventReader」它有一個peek方法,它可以在不迭代它的情況下返回下一個事件。一個非常好的教程可以在這裏找到,http://www.ibm.com/developerworks/library/x-stax2/index.html –