XPath filtering on attribute with namespace
Solution 1
That XPath looks correct.
It could be that your library doesn't support namespaced attributes, or that you haven't properly registered the yt
namespace and/or the media
namespace.
Try just matching on the local-name()
and namespace-uri()
inside of predicate filters, rather than using the namespace-prefix:
./*[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
If this works, then there is an issue registering the namespaces for those namespace-prefixes.
Solution 2
Assuming the rest is in order, simply replace the first .
in the xpath with /
to get //media:group/...
(or begin with /atom:feed/media:group/...
and register the atom namespace).
Here's a complete working example:
<?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 );
wurdalack
Updated on June 06, 2022Comments
-
wurdalack almost 2 years
I need to create XPath expression to filter based on attribute that is in given namespace. Example XML is:
<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>
And I need to get the url of the node with attribute yt:name set to 'hqdefault'.
I tried with XPath expression
'./media:group/media:thumbnail[@yt:name='hqdefault']/@url'
but it seems that specifying namespaced attribute with yt:name does not work. I get an empty DOMNodeList upon making a query.
I am accessing XML in php, so I registered yt namespace:
registerNamespace( 'yt', 'http://gdata.youtube.com/schemas/2007' );
Thnx in advance
-
wurdalack almost 13 yearsI did not enter the whole XML,sorry. It is YouTube playlist export XML and it starts with:
<feed xmlns='http://www.w3.org/2005/Atom' xmlns:media='http://search.yahoo.com/mrss/' xmlns:openSearch='http://a9.com/-/spec/opensearch/1.1/' xmlns:gd='http://schemas.google.com/g/2005' xmlns:yt='http://gdata.youtube.com/schemas/2007' gd:etag='W/"C04ESH47eCp7ImA9WhZWGUk."'>
I am accessing XML in php, so I registered yt namespace:registerNamespace( 'yt', 'http://gdata.youtube.com/schemas/2007' );
It does not work in sense that I get an empty DOMNodeList upon making a query. Thnx