Php SimplexmlElement-使用编程注册名称空间的xpath
我正在尝试用Xpath解析一些XML。我正在寻找的功能是,如果找不到现有前缀,则以编程方式使用特定前缀注册命名空间 当我在Xpath查询中使用前缀时,返回的是一个空数组,这表明Xpath是有效的,只是没有返回任何结果 下面是我正在使用的XML示例。请注意,这是我实际代码的简化版本,它是用来说明我的问题的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
$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花了我一段时间才明白你的意思!罗夫@詹瑟拉特-谢谢你的提醒,看起来我错过了一个位置