2010-12-16 2 views
1

Варианты этого вопроса заданы несколько раз здесь, но мой вопрос скорее является вопросом общей эффективности использования 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.

У меня есть подозрительное подозрение, что решение этой проблемы очень просто ... но я не могу полностью понять решение. Во всяком случае, я благодарю вас за ваше время!

ответ

1

Относительные вложенные XPaths - это путь.

Я возглавляю реализацию EclipseLink JAXB (MOXy), и мы предлагаем эту возможность с помощью аннотации @XmlPath. Если у вас уже есть XPaths, это будет относительно простое сопоставление.

Для получения дополнительной информации см: