Pregunta

Las variantes de esta pregunta se les ha pedido varias veces aquí, pero mi pregunta es más una cuestión de la eficiencia general de cómo usar XPath en Java.

Mi tarea: llevar artículos de Wikipedia sobre ubicaciones geográficas y crear una estructura de datos jerárquica de ellos.

Ya han obtenido versiones XML de las páginas wiki y reformateado de acuerdo con un esquema que tiene un sentido intuitivo. También he hecho una serie de clases muy simples que representan diferentes niveles de la jerarquía administrativa, como este:

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

Así como un método para agregar ciudades, algunos métodos get y set, y una toString ().

Este es un ejemplo del tipo de archivo XML que estoy tratando con:

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

Me esencialmente tiene una configuración funcional en este punto, pero el código es muy repetitivo y no tiene en cuenta la naturaleza inherente jerárquica de los datos geográficos. Idealmente, podría detener a un cierto nivel (digamos "centrarse" en una provincia en particular), y sólo se refieren a las cosas en términos relativos desde ese punto en adelante, para reducir al mínimo el número de veces que tengo que arrastrarse a través de todo el documento. A modo de ejemplo (nota, estoy usando una abstracción sobre la configuración tradicional de documentos, pero los métodos siguientes corresponden casi exactamente con los métodos tradicionales):

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

Francamente, esto parece tonto. No estoy tomando en cuenta el hecho de que todo lo relacionado con estas cadenas es idéntico una vez que llegue hasta el nivel que me interesa. No estoy con referencia a cualquier tipo de ruta relativa, y cada vez que atravesar una parte del documento que, de hecho, atravesar toda la cosa. Sería genial si pudiera bloquear el resto del documento XML original por un tiempo y sólo se centran en mi provincia, en referencia a todo lo que a partir de entonces en términos relativos.

En especial debe tener en cuenta que lo caro que está detrás de la abstracción "leer":

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

Soy esencialmente recompilando un patrón idéntico con un final ligeramente diferente? ¿Qué pasa con la carga de la parte de su interés y luego haciendo referencia a sus hijos con algo como "currProv / hanzi"?

He mirado en otros métodos de análisis de XML, y el "digestor" parece hacer algo similar a lo que quiero http://commons.apache.org/digester/core.html , pero ya tengo casi todo lo que hay en esta implementación XPath.

Tengo la sospecha persistente de que la solución a este problema es muy simple ... pero no acabo de entender la solución. De todos modos, gracias por su tiempo!

¿Fue útil?

Solución

XPaths anidadas relativas son el camino a seguir.

Me llevan a la aplicación EclipseLink JAXB (moxy) y ofrecemos esta capacidad a través de una anotación @XmlPath. Si ya tiene los XPath sería un mapeo relativamente fácil.

Para obtener más información, véase:

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top