2011-08-26 12 views
5

seguente è il mio file XMLrisultati XPath per stringa vuota

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

Quando ho Budila org.w3c.dom.Document da questo XML e XPathExperssion l'applicazione con l'espressione

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

risultati stringa vuota. Quale può essere il problema con l'espressione?

Grazie

risposta

6

Questo perché il documento XML utilizza uno spazio dei nomi. XPath è davvero fastidioso con gli spazi dei nomi. Per confermare ciò, elimina i due xmlns=http://.../v1 dal documento ed esegui nuovamente l'espressione XPath il file XML non verificabile, non verificabile. Corrisponderà.

Che cosa sta succedendo è che l'espressione XPath tenta di selezionare /xyzevent, quando il documento contiene {http://.../v1}:xyzevent, che non è la stessa cosa.

Esistono vari modi per risolvere questo problema. Il modo corretto è impostare un NamespaceContext in modo da poter utilizzare la notazione prefix:localName nell'espressione XPath e avere i prefissi da risolvere nell'URI corretto. C'è una breve descrizione su questo nel xerces docs e altri elsewhere on StackOverflow. C'è una descrizione estesa a ibm.com.

tuo NamespaceContext conterrà due (o più) mappature:

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

tua espressione XPath può quindi diventare /event:xyzevent/source:subscription/source:receiver/.../text().

Come un brutto soluzione , è possibile riscrivere la vostra espressione XPath per selezionare utilizzando la funzione local-name():

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

In questo caso, l'espressione corrisponde a qualsiasi elemento il cui nome locale è xyzevent, a prescindere dal namespace URI .

+0

Dopo aver rimosso xmlns = http: //.../v1 questo da entrambi i posti sono in grado di ottenere il valore. Ma puoi spiegarmi come creare NamespaceContext per ottenere quando abbiamo entrambi i valori del namespace nel documento ... – Pokuri

+0

@Pokuri Registra due prefissi separati nel tuo 'NamespaceContext', ad es. 'event' e' source' con gli URI corretti per ciascuno. La tua espressione XPath diventerà '/ event: xyzevent/source: subscription/source: receiver/...' – Barend

+0

Ma NamespaceContext si aspetta un namespaceURI e uno o più prefissi. Quindi, come posso passare due NamespaceContext a XPath.setNamespaceContext (namespaceContext); metodo – Pokuri

1

xyzevent è il vostro elemento radice, in modo che solo bisogno di usare "/subscription/receiver/clientsubscription/servicemap/text()".

2

Il tuo XML ha uno spazio dei nomi predefinito: xmlns="http://www.xyz.com/common/xyzevent/v1", pertanto è necessario definirlo nel tuo motore XML/XPath.

Oppure utilizzare questo XPath:

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