2011-08-26 11 views
5

私は、このXMLからのorg.w3c.dom.Documentをbudilaと表現のXPath結果

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

結果、空の文字列でXPathExperssionを適用する場合

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

私のXMLファイルです。表現の問題は何ですか?

答えて

6

これは、XMLドキュメントが名前空間を使用しているためです。 XPathは本当に名前空間を迷惑にしています。これを確認するには、文書からxmlns=http://.../v1の2つを取り除き、XPath式を再度実行します。これには、アンペアスペースの付いた確認できないXMLファイルがあります。それは一致します。

何が起こっているかは、ドキュメントに{http://.../v1}:xyzeventが含まれている場合、同じものではない場合、XPath式が/xyzeventを選択しようとしていることです。

この問題を回避する方法はさまざまです。正しい方法は、NamespaceContextを設定して、XPath式でprefix:localName表記を使用し、接頭辞を正しいURIに解決できるようにすることです。 xerces docsともう少しelsewhere on StackOverflowにこれについての短期間の宣伝があります。 ibm.comに詳しい説明があります。

あなたNamespaceContextは、2つ(またはそれ以上)のマッピングが含まれています:

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

あなたのXPath式は、/event:xyzevent/source:subscription/source:receiver/.../text()になることができます。 厄介な回避策として

、あなたがlocal-name()機能使用して選択するために、あなたのXPath式を書き換えることができます。この場合

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

を、式は関係なく、名前空間URIの、そのローカル名xyzeventある任意の要素にマッチします。

+0

xmlns = http://.../v1これを両方の場所から削除すると、値を取得できます。しかし、NamespaceContextをビルドして、ドキュメント内に名前空間の値が両方ある場合にどうすればいいのか説明できますか? – Pokuri

+0

@Pokuri名前空間コンテキストに2つの別々の接頭辞を登録します。 'event'と' source'をそれぞれ適切なURIで置き換えます。あなたのXPath式は '/ event:xyzevent/source:subscription/source:receiver/...になります。' – Barend

+0

しかしNamespaceContextは、namespaceURIと1つ以上の接頭辞を必要とします。次に、2つのNamespaceContextをXPath.setNamespaceContext(namespaceContext)に渡す方法はありますか。メソッド – Pokuri

1

xyzeventは、あなたのルート要素であるので、あなただけの"/subscription/receiver/clientsubscription/servicemap/text()"を使用する必要があります、ありがとうございました。

2

XMLにはデフォルトの名前空間:xmlns="http://www.xyz.com/common/xyzevent/v1"があるため、XML/XPathエンジンで定義する必要があります。

またはこのXPathの使用:

/*[local-name() = 'xyzevent'] 
    /*[local-name() = 'subscription'] 
     /*[local-name() = 'receiver'] 
      /*[local-name() = 'clientsubscription'] 
       /*[local-name() = 'servicemap'] 
        /text() 
関連する問題