Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/247.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php SimplexmlElement-使用编程注册名称空间的xpath_Php_Xml_Xpath_Simplexml - Fatal编程技术网

Php SimplexmlElement-使用编程注册名称空间的xpath

Php SimplexmlElement-使用编程注册名称空间的xpath,php,xml,xpath,simplexml,Php,Xml,Xpath,Simplexml,我正在尝试用Xpath解析一些XML。我正在寻找的功能是,如果找不到现有前缀,则以编程方式使用特定前缀注册命名空间 当我在Xpath查询中使用前缀时,返回的是一个空数组,这表明Xpath是有效的,只是没有返回任何结果 下面是我正在使用的XML示例。请注意,这是我实际代码的简化版本,它是用来说明我的问题的 $xml = <<<EOD <rss version="2.0"> <channel> <title> somdomain - R

我正在尝试用Xpath解析一些XML。我正在寻找的功能是,如果找不到现有前缀,则以编程方式使用特定前缀注册命名空间

当我在Xpath查询中使用前缀时,返回的是一个空数组,这表明Xpath是有效的,只是没有返回任何结果

下面是我正在使用的XML示例。请注意,这是我实际代码的简化版本,它是用来说明我的问题的

$xml =  <<<EOD
<rss version="2.0">
<channel>
    <title> somdomain - RSS Video Feed</title>
    <link>http://www.somdomain.com/</link>
    <description>Latest Videos Released on somdomain</description>
    <language>en-us</language>
    <pubDate>Thu, 19 Sep 2013 16:53:29 GMT</pubDate>
    <lastBuildDate>Thu, 19 Sep 2013 16:53:29 GMT</lastBuildDate>
    <image>
    <title>RSS Video Feed</title>
    <url>
    http://somdomain/cb/white.png
    </url>
    <link>http://www.somdomain.com/</link>
    </image>
    <link xmlns="http://www.w3.org/2005/Atom" href="http://www.somdomain.com/rss/" rel="self" type="application/rss+xml"/>
        <item>
            <title>The title </title>
            <link>
            http://www.somdomain.com/watch/8487128/
            </link>
            <description>
             <IMG border="1" src="http://cdn1.image.somdomain.php/8.jpg" />  <BR/> Length: 07:08 <BR/> Keywords:
            </description>
            <pubDate>Thu, 19 Sep 2013 16:00:11 GMT</pubDate>
            <guid>
            http://www.somdomain.com/watch/
            </guid>
        </item>
    </channel>
</rss>
EOD;
//default namespace
$d = "x";
$xml = new SimpleXMLElement($xml);
$ns = $xml->getNamespaces(true);
//there will only be one element here, $prefix is an empty string and 
// $url is http://www.w3.org/2005/Atom
foreach($ns as $prefix=>$url)
{
     //no prefix so use $d
    if($prefix=="")
    {
        $prefix = $d;
    }
    //register the namespace
    $xml->registerXPathNamespace($prefix, $url);
}


$result = $xml->xpath('/x:rss/x:channel/x:item');
//nothing
print_r($result);
$xml=registerXPathNamespace($prefix,$url);
}
$result=$xml->xpath('/x:rss/x:channel/x:item');
//没什么
打印(结果);
我不知道这为什么不起作用。我认为注册名称空间本质上应该是现有名称空间的别名,因此“x:rss/x:channel/x:item”应该是一个有效的查询。谁能告诉我我做错了什么?如有任何建议,将不胜感激。谢谢

元素
没有定义名称空间,只有
元素(以及所有子元素)具有此名称空间

使用查询

/rss/channel/item
相反。如果开始选择此
元素(或低于该元素),则需要名称空间:

/rss/channel/x:link/@href
元素没有定义名称空间,只有
元素(以及所有子元素)有此名称空间

使用查询

/rss/channel/item
相反。如果开始选择此
元素(或低于该元素),则需要名称空间:

/rss/channel/x:link/@href

首先,根据XPath在文档中的别名为其注册名称空间通常是一个坏主意:这看起来可能更容易,但前缀可能会在不通知的情况下更改,而实际的名称空间名称(URI)将保持不变。(例如,生成的代码可能只使用前缀,如
ns1:
ns2:
,等等;这些前缀在以后很容易交换)

相反,您应该查看您关心的实际名称空间,并为它们选择自己的前缀。在本例中,您的注释已经指出,唯一涉及的名称空间是
http://www.w3.org/2005/Atom
。如果以后添加了前缀,您将不会有任何代码使用它们,因此为它们注册前缀对您没有任何好处

因此,用这一行替换整个循环:

 $xml->registerXPathNamespace('x', 'http://www.w3.org/2005/Atom');
其次,您必须考虑哪些元素实际位于该名称空间中。尽管它没有前缀,但它是在
链接
元素中声明的,因此它仅作为文档该部分的默认名称空间应用。在该“范围”之外,没有
xmlns
属性来声明默认名称空间,因此名称空间中没有名称

同样,要在XPath中引用这些元素,根本不使用名称空间前缀:

$result = $xml->xpath('/rss/channel/item');

首先,根据XPath在文档中的别名为其注册名称空间通常是一个坏主意:这看起来可能更容易,但前缀可能会在没有通知的情况下更改,而实际名称空间名称(URI)将保持不变。(例如,生成的代码可能只使用前缀,如
ns1:
ns2:
,等等;这些前缀在以后很容易交换)

相反,您应该查看您关心的实际名称空间,并为它们选择自己的前缀。在本例中,您的注释已经指出,唯一涉及的名称空间是
http://www.w3.org/2005/Atom
。如果以后添加了前缀,您将不会有任何代码使用它们,因此为它们注册前缀对您没有任何好处

因此,用这一行替换整个循环:

 $xml->registerXPathNamespace('x', 'http://www.w3.org/2005/Atom');
其次,您必须考虑哪些元素实际位于该名称空间中。尽管它没有前缀,但它是在
链接
元素中声明的,因此它仅作为文档该部分的默认名称空间应用。在该“范围”之外,没有
xmlns
属性来声明默认名称空间,因此名称空间中没有名称

同样,要在XPath中引用这些元素,根本不使用名称空间前缀:

$result = $xml->xpath('/rss/channel/item');

顺便说一下,您可能需要编辑
//title
元素,因为您已经删除了所有这些URL@JensErat花了我一段时间才明白你的意思!罗夫@JensErat-谢谢你的提醒,看起来我错过了一点顺便说一句,你可能想编辑
//title
元素,因为你已经删除了所有的URL@JensErat花了我一段时间才明白你的意思!罗夫@詹瑟拉特-谢谢你的提醒,看起来我错过了一个位置