這個問題的變體現在已經有幾次被問到了,但我的問題更多的是在Java中使用XPATH的一般效率問題。使用Java中的XPATH處理分層XML文檔。效率?
我的任務:獲取維基百科關於地理位置的文章,並從中創建分層數據結構。
我已經獲得了wiki版本的XML版本,並根據一個直觀的模式進行了重新格式化。我也讓代表不同級別的行政層級,如這一系列非常簡單的類:
public class Province implements java.io.Serializable {
private ArrayList<City> cities = new ArrayList<City>();
private String hanzi;
private String pinyin;
public Province(String hanzi, String pinyin) {
this.hanzi = hanzi;
this.pinyin = pinyin;
}
除了增加城市,一些getter和setter方法的方法和一個toString()。
這裏是我處理XML文件的類型的示例:
<mediawiki>
<page>
<title>Tianjin</title>
<revision>
<id>2064019</id>
<text xml:space="preserve">
<province>
<hanzi>天津</hanzi>
<pinyin>Tianjin</pinyin>
<Level2>
<hanzi>和平</hanzi>
<pinyin>Heping</pinyin>
<zip>300000</zip>
</Level2>
<Level2>
<hanzi>河東</hanzi>
<pinyin>Hedong</pinyin>
<zip>300000</zip>
</Level2>
</province>
</text>
</revision>
</page>
...
</mediawiki>
我基本上都在這一點上的功能設置,但代碼是非常重複,不考慮地理數據的固有層次性。理想情況下,我可以在某個層次上停下來(讓我們說「專注於某個特定的省份)」,並且只是從相關的角度來提及事情的前進方向,以便儘量減少抓取整個文檔的次數。作爲一個例子(注意,我使用了傳統的文檔建立一個抽象的,但下面的方法對應幾乎完全與傳統方法):
XPathReader reader = new XPathReader("sourceXML\\Provinces.xml");
String expression = "/mediawiki/page";
NodeList allProvinces = (NodeList)reader.read(expression, XPathConstants.NODESET);
for(int i=0; i < allProvinces.getLength(); i++) {
expression = "/mediawiki/page[" + i + "]/revision/text/province/hanzi";
String hanzi = reader.read(expression, XPathConstants.STRING).toString();
expression = "/mediawiki/page[" + i + "]/revision/text/province/pinyin";
String pinyin = reader.read(expression, XPathConstants.STRING).toString();
Province currProv = new Province(hanzi, pinyin);
expression = "/mediawiki/page[" + i + "]/revision/text/province/Level2";
NodeList level2 = (NodeList)reader.read(expression, XPathConstants.NODESET);
for(int j=1; j < level2.getLength(); j++) {
expression = "/mediawiki/page[" + i + "]/revision/text/province/Level2[" + j + "]/hanzi";
String hanzi2 = reader.read(expression, XPathConstants.STRING).toString();
expression = "/mediawiki/page[" + i + "]/revision/text/province/Level2[" + j + "]/pinyin";
String pinyin2 = reader.read(expression, XPathConstants.STRING).toString();
City currCity = new City(hanzi2, pinyin2);
currProv.add(currCity);
...
}
}
坦率地講,這似乎是愚蠢的。我沒有考慮到這樣的事實,即一旦我達到我所關心的級別,這些字符串的所有內容都是相同的。我沒有引用任何一種相對路徑,每當我遍歷文檔的一部分時,我實際上遍歷整個事物。如果我能夠暫時阻止原始XML文檔的其餘部分,並且只關注我的省份,這將是非常好的,指的是相對而言的所有事情。
我應該特別注意的是多麼昂貴,這是背後的「讀」抽象:
xPath.compile(expression);
String result = xPathExpression.evaluate (xmlDocument, returnType);
我基本上是重新編譯相同的圖案略有不同的結局?加載感興趣的部分,然後用「currProv/hanzi」來引用它的孩子呢?
我已經研究瞭解析XML的其他方法,「Digester」似乎做了類似於我想要的東西http://commons.apache.org/digester/core.html,但是我已經在這個XPATH實現中擁有幾乎所有的東西。
我對這個問題的解決方案非常簡單,我有嘮叨的懷疑......但我無法完全理解解決方案。無論如何,我感謝你的時間!