Варианты этого вопроса заданы несколько раз здесь, но мой вопрос скорее является вопросом общей эффективности использования XPATH в Java.Обработка иерархического документа XML с помощью XPATH в Java. Эффективность?
Моя задача: взять статьи из Википедии о географических местоположениях и создать из них иерархическую структуру данных.
Я уже получил 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;
}
, а также метод, чтобы добавить города, некоторые методы получения и установки, и 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.
У меня есть подозрительное подозрение, что решение этой проблемы очень просто ... но я не могу полностью понять решение. Во всяком случае, я благодарю вас за ваше время!