Pregunta

Quiero usar JDOM para leer en un archivo XML, a continuación, utilizar XPath para extraer los datos del documento JDOM. Se crea el objeto de documento fina, pero cuando se utiliza XPath para consultar el documento para una lista de elementos, que no reciben nada.

Mi documento XML tiene un espacio de nombres predeterminado definido en el elemento raíz. Lo curioso es que, cuando se quita el espacio de nombres por defecto, se ejecuta correctamente la consulta XPath y devuelve los elementos que quiero. ¿Qué más tengo que hacer para conseguir mi consulta XPath para devolver resultados?

XML:

<?xml version="1.0" encoding="UTF-8"?>
<collection xmlns="http://www.foo.com">
<dvd id="A">
  <title>Lord of the Rings: The Fellowship of the Ring</title>
  <length>178</length>
  <actor>Ian Holm</actor>
  <actor>Elijah Wood</actor>
  <actor>Ian McKellen</actor>
</dvd>
<dvd id="B">
  <title>The Matrix</title>
  <length>136</length>
  <actor>Keanu Reeves</actor>
  <actor>Laurence Fishburne</actor>
</dvd>
</collection>

Java:

public static void main(String args[]) throws Exception {
    SAXBuilder builder = new SAXBuilder();
    Document d = builder.build("xpath.xml");
    XPath xpath = XPath.newInstance("collection/dvd");
    xpath.addNamespace(d.getRootElement().getNamespace());
    System.out.println(xpath.selectNodes(d));
}
¿Fue útil?

Solución

XPath 1.0 no soporta el concepto de un espacio de nombres predeterminado ( XPath 2.0 hace).  Cualquier etiqueta sin prefijo siempre se supone que es parte del espacio de nombres sin nombre.

Cuando se utiliza XPath 1.0 se necesita algo como esto:

public static void main(String args[]) throws Exception {
    SAXBuilder builder = new SAXBuilder();
    Document d = builder.build("xpath.xml");
    XPath xpath = XPath.newInstance("x:collection/x:dvd");
    xpath.addNamespace("x", d.getRootElement().getNamespaceURI());
    System.out.println(xpath.selectNodes(d));
}

Otros consejos

He tenido un problema similar, pero la mía era que tenía una mezcla de entradas XML, algunos de los cuales tenían un espacio de nombres definido y otros que no lo hicieron. Para simplificar mi problema me encontré con el siguiente fragmento de JDOM después de cargar el documento.

for (Element el : doc.getRootElement().getDescendants(new ElementFilter())) {
    if (el.getNamespace() != null) el.setNamespace(null);
}

Después de la eliminación de todos los espacios de nombres que fue capaz de utilizar simples GetChild ( "elname") navegación estilo o XPath simples consultas.

No recomendaría esta técnica como una solución general, pero en mi caso fue sin duda útil.

También puede hacer lo siguiente

/*[local-name() = 'collection']/*[local-name() = 'dvd']/

Aquí está la lista de consultas XPath útil.

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