PHP 5.4.14 を実行しており、XPath を使用して XML ドキュメント内を検索しようとしています。各ネームスペースにどのネームスペース プレフィックスが使用されるか分からないので、 を使用して独自のプレフィックスを定義しますregisterXPathNamespace()
。
問題は、XPath の新しいプレフィックス (例: C
) を登録し、ドキュメントが既にそれを使用している場合、XPath クエリは私のプレフィックスではなく元のプレフィックスを使用することです。
この動作を示すサンプル コードを示します。
<?php
$body = <<<EOF
<multistatus xmlns="DAV:" xmlns:VC="urn:ietf:params:xml:ns:carddav" xmlns:C="urn:ietf:params:xml:ns:caldav" xmlns:C1="http://calendarserver.org/ns/">
<response>
<href>/caldav.php/jorge/contacts/</href>
<propstat>
<prop>
<current-user-principal>
<href>/caldav.php/jorge/</href>
</current-user-principal>
<resourcetype>
<collection/>
<VC:addressbook/>
</resourcetype>
<displayname/>
<VC:addressbook-home-set>
<href>/caldav.php/jorge/</href>
</VC:addressbook-home-set>
</prop>
<status>HTTP/1.1 200 OK</status>
</propstat>
</response>
</multistatus>
EOF;
$xml = new SimpleXMLElement($body);
$xml->registerXPathNamespace('C', 'urn:ietf:params:xml:ns:carddav');
$xpresult = $xml->xpath('//C:addressbook-home-set');
var_dump($xpresult);
実行すると、クエリが結果を返さないことがわかります。
驚いたことに、登録されたプレフィックスをCからXなど、まだ定義されていない他のプレフィックスに変更すると、クエリは期待どおりに機能します。
$xml->registerXPathNamespace('X', 'urn:ietf:params:xml:ns:carddav');
$xpresult = $xml->xpath('//X:addressbook-home-set');
私は何か間違ったことをしていますか?どのプレフィックスが使用されるかを事前に知ることができない場合、カスタム プレフィックスを設定して、醜いMYPROGRAMUNUSEDPREFIXCプレフィックスを使用する以外に、ドキュメント内の他のプレフィックスと競合しないようにすることは可能ですか?
ドキュメントで使用されているプレフィックスと名前空間を取得できることはわかっていますが、XPath クエリ文字列を修正したいと考えています。
FWIW DOMXPath にもこの問題があります (チェック済み)。