downloads | documentation | faq | getting help | mailing lists | licenses | wiki | reporting bugs | php.net sites | links | conferences | my php.net

search for in the

SimpleXMLElement::xpath> <SimpleXMLElement::getNamespaces
Last updated: Fri, 13 Nov 2009

view this page in

SimpleXMLElement::registerXPathNamespace

(PHP 5 >= 5.2.0)

SimpleXMLElement::registerXPathNamespace 次の XPath クエリ用の prefix/ns コンテキストを作成する

説明

bool registerXPathNamespace ( string $prefix , string $ns )

次の XPath クエリ用の prefix/ns コンテキストを作成します。特にこれが有用なのは、 XML ドキュメントの提供者が名前空間プレフィックスを変更したような場合です。 registerXPathNamespace はプレフィックスを作成して名前空間に関連付け、 そのプレフィックスで名前空間のノードにアクセスできるようにします。 提供者側がプレフィックスを変更したとしても、コードを書き換える必要はありません。

パラメータ

prefix

ns で指定した名前空間への XPath クエリで使用する、 名前空間プレフィックス。

ns

XPath クエリで使用する名前空間。 これは XML ドキュメントで使用している名前空間と一致していなければなりません。 一致していない場合、prefix を使用した XPath クエリは何も結果を返しません。

返り値

成功した場合に TRUE を、失敗した場合に FALSE を返します。

例1 XPath クエリで使用する名前空間プレフィックスの設定

<?php

$xml 
= <<<EOD
<book xmlns:chap="http://example.org/chapter-title">
    <title>My Book</title>
    <chapter id="1">
        <chap:title>Chapter 1</chap:title>
        <para>Donec velit. Nullam eget tellus vitae tortor gravida scelerisque. 
            In orci lorem, cursus imperdiet, ultricies non, hendrerit et, orci. 
            Nulla facilisi. Nullam velit nisl, laoreet id, condimentum ut, 
            ultricies id, mauris.</para>
    </chapter>
    <chapter id="2">
        <chap:title>Chapter 2</chap:title>
        <para>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Proin 
            gravida. Phasellus tincidunt massa vel urna. Proin adipiscing quam 
            vitae odio. Sed dictum. Ut tincidunt lorem ac lorem. Duis eros 
            tellus, pharetra id, faucibus eu, dapibus dictum, odio.</para>
    </chapter>
</book>
EOD;

$sxe = new SimpleXMLElement($xml);

$sxe->registerXPathNamespace('c''http://example.org/chapter-title');
$result $sxe->xpath('//c:title');

foreach (
$result as $title) {
  echo 
$title "\n";
}

?>

上の例の XML ドキュメントでは、プレフィックス chap で名前空間を指定していることを確認しておきましょう。仮に、このドキュメント (あるいはよく似た別のドキュメント) が以前に同じ名前空間に対してプレフィックス c を使用していたとしましょう。プレフィックスが変わった時点で、 これまでの XPath クエリは正しい値を返さないようになります。 そしてクエリに対して何らかの変更が必要となります。 registerXPathNamespace を使用すると、 仮に名前空間プレフィックスが変更された場合でもクエリの変更する必要がなくなります。

参考



SimpleXMLElement::xpath> <SimpleXMLElement::getNamespaces
Last updated: Fri, 13 Nov 2009
 
add a note add a note User Contributed Notes
SimpleXMLElement::registerXPathNamespace
wouter at code dot nl
10-Jul-2009 12:18
A problem occurs when the XML document you want to parse does not declare a namespace consistently; sometimes it does declare the namespace, sometimes not.

Your XPath queries will fail if you use the ns prefix in your query while it is not declared in the XML (resulting in this error: "SimpleXMLElement::xpath() [simplexmlelement.xpath]: Undefined namespace prefix"). On the other hand the query will also fail if you don't use the prefix if the namespace is declared in the XML (will return an empty result).

Since you can only register a namespace prefix for XPath if the namespace is declared (registerXPathNamespace()), the only way to cope with this, is to write the prefix in your XPath queries with a little variable.

eg.

<?php
// get used namespaces
$namespaces = $this->simple_xml->getNamespaces(TRUE);

// say namespace 'pre:' is not defined consistently
// define namespace prefix var for xpath queries
$this->ns_prefix = isset($namespaces['pre']) ? 'pre:' : '';

// your xpath queries look like this (section/pre:value or section/value)
$res = $this->simple_xml->xpath('section/'. $this->ns_prefix .'value');
?>

It is not an elegant solution but it I couldn't find a better one. (Add a registerNamespace($prefix, $url) method? ;))
remy dot damour at -please-no-spam-laposte dot net
16-Jan-2009 01:28
Registering xpath-namespaces is mandatory when your input xml has a default namespace.

Unfortunately an empty prefix '' cannot be registered, I use 'default' as prefix:
<?php
$sxe
->registerXPathNamespace('default', 'mynamespace');
// then
$sxe->xpath('//default:nodename');
?>

Bad news is that xpath-namespaces must be registered on EVERY SimpleXMLElement on which ->xpath() is to be called! (registering it on root node is not sufficient)
daniel dot oconnor at gmail dot com
30-Jul-2008 01:45
A handy timesaver:

<?php
$sxe
= simplexml_load_file($path);

//Fetch all namespaces
$namespaces = $sxe->getNamespaces(true);

//Register them with their prefixes
foreach ($namespaces as $prefix => $ns) {
   
$sxe->registerXPathNamespace($prefix, $ns);
}
?>

SimpleXMLElement::xpath> <SimpleXMLElement::getNamespaces
Last updated: Fri, 13 Nov 2009
 
 
show source | credits | stats | sitemap | contact | advertising | mirror sites