Php 对具有命名空间的属性进行XPath筛选

Php 对具有命名空间的属性进行XPath筛选,php,xml,xslt,xpath,Php,Xml,Xslt,Xpath,我需要创建XPath表达式,以便根据给定命名空间中的属性进行筛选。示例XML是: <feed xmlns='http://www.w3.org/2005/Atom' xmlns:media='http://search.yahoo.com/mrss/' xmlns:yt='http://gdata.youtube.com/schemas/2007'> ... <entry> <media:group> <media:thumbnail u

我需要创建XPath表达式,以便根据给定命名空间中的属性进行筛选。示例XML是:

<feed xmlns='http://www.w3.org/2005/Atom' xmlns:media='http://search.yahoo.com/mrss/'
  xmlns:yt='http://gdata.youtube.com/schemas/2007'> ...
 <entry>
  <media:group>
   <media:thumbnail url='http://i.ytimg.com/1.jpg' yt:name='default'/>
   <media:thumbnail url='http://i.ytimg.com/2.jpg' yt:name='hqdefault'/>
   <media:thumbnail url='http://i.ytimg.com/3.jpg' yt:name='start'/>
   <media:thumbnail url='http://i.ytimg.com/4.jpg' yt:name='middle'/>
  </media:group>
 </entry>
但使用yt:name指定名称空间属性似乎不起作用。我在查询时得到一个空的域名列表

我正在用php访问XML,所以我注册了yt名称空间:

registerNamespace( 'yt', 'http://gdata.youtube.com/schemas/2007' );

Thnx预先

示例XML中使用了
yt
名称空间前缀,但未声明。如果这个示例XML真的是全部,那么它不是格式良好的XML(在名称空间方面)。因此,像XSLT这样的通用XML工具不可能处理它

另一方面,如果源文档中有一个未向我们展示的
yt
名称空间前缀声明,那么您需要在XPath处理环境(我猜是XSLT)中为相同的名称空间URI声明一个前缀。例如

<xsl:stylesheet ... xmlns:yt="theNamespaceURIForYT">


XPath不知道源文档中出现的任何名称空间前缀声明。它只知道每个元素(和属性)所属的名称空间(URI)。

XPath看起来是正确的

可能是您的库不支持命名空间属性,或者您没有正确注册
yt
命名空间和/或
媒体
命名空间

尝试在谓词筛选器内部匹配
local-name()
namespace-uri()
,而不是使用名称空间前缀:

./*[local-name()='group'
      and namespace-uri()='http://search.yahoo.com/mrss/'
    ]/*[local-name()='thumbnail'
         and namespace-uri()='http://search.yahoo.com/mrss/'
         and @*[local-name()='name'
                 and namespace-uri()='http://gdata.youtube.com/schemas/2007'
                 and .='hqdefault'
                ]
        ]/@url

如果这样做有效,那么为这些名称空间前缀注册名称空间就会出现问题。

假设其余的都正常,只需将xpath中的第一个
替换为
/
,即可获得
//media:group/..
(或者以
/atom:feed/media:group/..
开头并注册atom名称空间)

下面是一个完整的工作示例:

<?php
$dom = new DOMDocument();
$dom->loadXML( <<<XML
<feed xmlns='http://www.w3.org/2005/Atom' xmlns:media='http://search.yahoo.com/mrss/'
  xmlns:yt='http://gdata.youtube.com/schemas/2007'>
  <entry>
    <media:group>
      <media:thumbnail url='http://i.ytimg.com/1.jpg' yt:name='default'/>
      <media:thumbnail url='http://i.ytimg.com/2.jpg' yt:name='hqdefault'/>
      <media:thumbnail url='http://i.ytimg.com/3.jpg' yt:name='start'/>
      <media:thumbnail url='http://i.ytimg.com/4.jpg' yt:name='middle'/>
    </media:group>
  </entry>
</feed>
XML
);

$x = new DOMXPath( $dom );
$x->registerNamespace( 'yt', 'http://gdata.youtube.com/schemas/2007' );
$x->registerNamespace( 'media', 'http://search.yahoo.com/mrss/' );
$l= $x->query( "//media:group/media:thumbnail[@yt:name='hqdefault']/@url" );
for ($i=0; $i<$l->length; $i++) var_dump( $l->item($i)->value );
项目($i)->价值);

“不起作用”-您需要说明发生了什么。错误消息?对不起,我没有输入整个XML。这是YouTube播放列表导出XML,它的开头是:
我正在用php访问XML,所以我注册了yt名称空间:
registerNamespace('yt','http://gdata.youtube.com/schemas/2007' );如果我在进行查询时得到一个空的DOMNodeList,那么它就不起作用了。Thnx
<?php
$dom = new DOMDocument();
$dom->loadXML( <<<XML
<feed xmlns='http://www.w3.org/2005/Atom' xmlns:media='http://search.yahoo.com/mrss/'
  xmlns:yt='http://gdata.youtube.com/schemas/2007'>
  <entry>
    <media:group>
      <media:thumbnail url='http://i.ytimg.com/1.jpg' yt:name='default'/>
      <media:thumbnail url='http://i.ytimg.com/2.jpg' yt:name='hqdefault'/>
      <media:thumbnail url='http://i.ytimg.com/3.jpg' yt:name='start'/>
      <media:thumbnail url='http://i.ytimg.com/4.jpg' yt:name='middle'/>
    </media:group>
  </entry>
</feed>
XML
);

$x = new DOMXPath( $dom );
$x->registerNamespace( 'yt', 'http://gdata.youtube.com/schemas/2007' );
$x->registerNamespace( 'media', 'http://search.yahoo.com/mrss/' );
$l= $x->query( "//media:group/media:thumbnail[@yt:name='hqdefault']/@url" );
for ($i=0; $i<$l->length; $i++) var_dump( $l->item($i)->value );