2010-12-16 8 views
1

Varianten dieser Frage wurden hier schon mehrmals gestellt, aber meine Frage ist mehr eine Frage der allgemeinen Effizienz der Verwendung von XPATH in Java.Verarbeiten eines hierarchischen XML-Dokuments mit XPATH in Java. Effizienz?

Meine Aufgabe: wikipedia Artikel über geografische Standorte aufnehmen und daraus eine hierarchische Datenstruktur erstellen.

Ich habe bereits XML-Versionen der Wiki-Seiten erhalten und nach einem Schema neu formatiert, das intuitiven Sinn macht. Ich habe auch eine Reihe von sehr einfachen Klassen, die verschiedene Ebenen der Verwaltungshierarchie, wie folgt aus:

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; 
} 

Neben einer Methode Städte hinzufügen, einige Getter und Setter-Methoden und eine toString().

Hier ist ein Beispiel für die Art von XML-Datei mit mir zu tun habe:

<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> 

Ich habe im Wesentlichen eine funktionelle Einrichtung an dieser Stelle, aber der Code ist extrem repetitiv und berücksichtigt nicht in der inhärente hierarchische Natur geographischer Daten. Im Idealfall könnte ich auf einer bestimmten Ebene anhalten (sagen wir "auf eine bestimmte Provinz fokussieren"), und von diesem Punkt an nur in relativer Weise auf Dinge Bezug nehmen, um die Anzahl der Durchforstungen durch das gesamte Dokument zu minimieren. Als Beispiel (beachten Sie, ich eine Abstraktion über den traditionellen Document Setup verwenden, aber die Methoden unten entsprechen fast genau die traditionellen Methoden):

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); 
... 
    } 
} 

Ehrlich gesagt, scheint dies stumm. Ich berücksichtige nicht die Tatsache, dass alles über diese Saiten identisch ist, sobald ich auf die Ebene komme, die mir wichtig ist. Ich verweise nicht auf irgendeinen relativen Pfad, und wenn ich einen Teil des Dokuments durchquere, durchquere ich tatsächlich das ganze Ding. Es wäre großartig, wenn ich den Rest des ursprünglichen XML-Dokuments für eine Weile aussperren und mich nur auf meine Provinz konzentrieren könnte, wobei ich mich auf alles beziehen würde, was von nun an relativ ist.

Ich soll besonders beachten, dass, wie teuer diese hinter der „lesen“ Abstraktion ist:

xPath.compile(expression); 
String result = xPathExpression.evaluate (xmlDocument, returnType); 

ich im Wesentlichen mit einem etwas anderen Ende ein identisches Muster bin neu zu kompilieren? Wie wäre es, den Teil des Interesses zu laden und dann mit etwas wie "currProv/hanzi" auf seine Kinder zu verweisen?

Ich habe in andere Methoden der Analyse von XML untersucht, und der "Digester" scheint etwas zu tun, was ich möchte http://commons.apache.org/digester/core.html, aber ich habe bereits fast alles dort in dieser XPATH-Implementierung.

Ich habe den nagenden Verdacht, dass die Lösung für dieses Problem sehr einfach ist ... aber ich kann die Lösung nicht ganz begreifen. Wie auch immer, ich danke dir für deine Zeit!

Antwort