次のXMLがあります。
<List xmlns="http://schemas.Microsoft.com/sharepoint/soap/">
<Fields>
<Field>
</Field>
</Fields>
</List>
これは、SharePoint Webサービスから返されるXMLのスリムバージョンです。次のxPathもあります。
/List/Fields/Field
XMLからxmlns
を削除すると、xPathは正常に機能します。そこにあるとき、私のxPathは何も見つけません。 xPathで別の方法でやるべきことはありますか? XMLの変更はオプションではありません。
次のxPathもあります。
/List/Fields/Field
XMLからxmlnsを削除すると、xPathは正常に機能します。それがそこにあるとき、私のxPathは何も見つけません
名前空間バインディングを登録できず、使用できない場合(登録されたプレフィックスが「x」であると仮定):
/x:List/x:Fields/x:Field
その後、別の方法があります:
/*[name()='List']/*[name()='Fields']/*[name()='Field']
List要素はデフォルトの名前空間で定義されており、これは内部のすべての要素に採用されています。
したがって、次のように要素の名前空間を無視する必要があります。
/*[local-name()='List']/*[local-name()='Fields]/*[local-name()='Field]
しかし、これはxpathがList-Fields-Fieldで他の要素を取得することを意味します
次のような名前空間チェックとローカル名チェックを実行できます。
/*[local-name()='List' and namespace-uri()='http://schemas.Microsoft.com/sharepoint/soap/']/*[local-name()='Fields' and namespace-uri()='http://schemas.Microsoft.com/sharepoint/soap/']/*[local-name()='Field' and namespace-uri()='http://schemas.Microsoft.com/sharepoint/soap/']
または、名前空間をライブラリに登録し、その名前空間のプレフィックスを明示的に指定して、使用しているライブラリに依存するメソッドをxpath式に追加できます。
ほとんどの場合、その名前空間uriをxpathライブラリに登録する必要があります。ライブラリによっては、「デフォルト」プレフィックスを使用できる場合もあれば、名前付きプレフィックスを指定してxpathクエリで使用する必要がある場合もあります。
たとえば、PHPで(言語を指定しなかったため)DOMXPathを使用すると、次のようなことができます。
$xpath = new DOMXPath($document);
$xpath->registerNamespace('x', 'http://schemas.Microsoft.com/sharepoint/soap/');
$xpath->query('/x:List/x:Fields/x:Field');
Xalan-cを使用しているときにこの問題が発生しました。
私が最初にまったく得なかったのは、XPathまたはXSLT名前空間のエイリアス/プレフィックスが、名前空間リゾルバに応じてドキュメントのエイリアス/プレフィックスと異なる場合があるということです。
ドキュメントに名前空間がある場合、名前空間が使用されない限り、パス要素との一致に失敗するようです。 (標準ですが、常に従わない?)
XalanDocumentPrefixResolverは、XPathまたはXSLT名前空間をURIにマップし、接頭辞を取得してIDを与えます-接頭辞がない場合、xmlnsになった名前を使用します
/xmlns:List/xmlns:Fields/xmlns:Field
または、独自のリゾルバを作成することもできますが、それでもxpathで使用される最小限の名前空間が必要です:(
これはテスト中に一緒にハッキングしたもので、メモリの保証はありません
// don't care what prefix given, there can only be the one
struct NoPrefixResolver : public xalanc::PrefixResolver {
NoPrefixResolver(const xalanc::XalanDOMString& theURI) : m_uri(theURI){}
virtual const xalanc::XalanDOMString*
getNamespaceForPrefix(const xalanc::XalanDOMString& prefix) const {
return &m_uri;
}
virtual const xalanc::XalanDOMString& getURI() const {
return m_uri;
}
const xalanc::XalanDOMString m_uri;
};
/x:List/x:Fields/x:Field
/a:List/b:Fields/c:Field