2011-08-26 21 views
5

que sigue es mi archivo XMLXPath resultados a cadena vacía

<xyzevent xmlns="http://www.xyz.com/common/xyzevent/v1" xmlns:xsi="http://www.w3.org2001XMLSchema-instance"> 
<header> 
---- 
</header> 
<subscription xmlns="http://www.xyz.com/common/xyzevent/source/v1"> 
    <sender></sender> 
    <receiver> 
    <clientsubscription> 
     <servicemap>nanna</servicemap> 
    </clientsubscription> 
    </receiver> 
</subscription> 
</xyzevent> 

Cuando Budila org.w3c.dom.Document de este XML y aplicar XPathExperssion con la expresión

/xyzevent/subscription/receiver/clientsubscription/servicemap/text() 

resultados cadena vacía. ¿Cuál puede ser el problema con la expresión?

Gracias

Respuesta

6

Esto se debe a que su documento XML usa un espacio de nombres. XPath es realmente molesto con espacios de nombres. Para confirmar esto, quite los dos xmlns=http://.../v1 del documento y ejecute su expresión XPath contra el archivo XML no enmascarado y no verificable. Coincidirá.

Lo que sucede es que su expresión XPath intenta seleccionar /xyzevent, cuando su documento contiene {http://.../v1}:xyzevent, que no es lo mismo.

Existen varias formas de solucionar este problema. La forma correcta es configurar un NamespaceContext para que pueda usar la notación prefix:localName en su expresión XPath y hacer que los prefijos se resuelvan en el URI correcto. Hay una breve reseña sobre esto en el xerces docs y algunos más elsewhere on StackOverflow. Hay una descripción extensa en ibm.com.

Su NamespaceContext contendrá dos (o más) asignaciones:

{ 
    event => http://www.xyz.com/common/xyzevent/v1 
    source => http://www.xyz.com/common/xyzevent/source/v1 
} 

Su expresión XPath puede entonces convertirse en /event:xyzevent/source:subscription/source:receiver/.../text().

Como desagradable solución , se puede reescribir su expresión XPath para seleccionar usando la función local-name():

/*[local-name()='xyzevent']/*[local-name()='subscription'/ ... 

En este caso, la expresión coincide con cualquier elemento cuyo nombre local es xyzevent, independientemente de la URI de espacio .

+0

Después de eliminar xmlns = http: //.../v1 esto de ambos lugares, puedo obtener el valor. Pero puede explicarme cómo crear NamespaceContext para obtener cuando tengamos los dos valores de espacio de nombres en el documento ... – Pokuri

+0

@Pokuri Registre dos prefijos separados en su 'NamespaceContext', p. 'evento' y' fuente' con los URI apropiados para cada uno. Su expresión XPath se convertirá en '/ event: xyzevent/source: subscription/source: receiver/...' – Barend

+0

Pero NamespaceContext espera un namespaceURI y uno o más prefijos. Entonces, ¿cómo puedo pasar dos NamespaceContext a XPath.setNamespaceContext (namespaceContext); método – Pokuri

1

xyzevent es su elemento raíz, por lo que sólo tiene que utilizar "/subscription/receiver/clientsubscription/servicemap/text()".

2

Su XML tiene espacio de nombre predeterminado: xmlns="http://www.xyz.com/common/xyzevent/v1", por lo tanto, debe definirlo en su motor XML/XPath.

O utilizar este XPath:

/*[local-name() = 'xyzevent'] 
    /*[local-name() = 'subscription'] 
     /*[local-name() = 'receiver'] 
      /*[local-name() = 'clientsubscription'] 
       /*[local-name() = 'servicemap'] 
        /text() 
Cuestiones relacionadas