2011-08-04 9 views
10

Necesito crear una expresión XPath para filtrar en función del atributo que se encuentra en el espacio de nombres dado. Ejemplo XML es:Filtrado de XPath en el atributo con el espacio de nombres

<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> 

y necesito para obtener la url del nodo con yt atributo: nombre del conjunto de 'hqdefault'.

me trataron con la expresión XPath

'./media:group/media:thumbnail[@yt:name='hqdefault']/@url' 

pero parece que al especificar un espacio de nombres de atributos con yt: nombre no funciona. Obtengo una DOMNodeList vacía al hacer una consulta.

Yo soy el acceso a XML en PHP, por lo que he registrado yt espacio de nombres:

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

Thnx de antemano

+0

"no funciona" - que tiene que decir lo que sucede. Un mensaje de error? – LarsH

Respuesta

0

El prefijo yt espacio de nombres se utiliza en su ejemplo XML, pero no se declara. Si ese XML de ejemplo es realmente todo lo que hay, no es un XML bien formado (en términos de espacio de nombres). Por lo tanto, es probable que ninguna herramienta XML genérica, como XSLT, pueda procesarla.

Por otro lado, si hay una declaración del prefijo del espacio de nombres yt en algún lugar de su documento fuente que no nos ha mostrado, entonces debe declarar en su entorno de procesamiento XPath (XSLT supongo) un prefijo para el URI del mismo espacio de nombres. P.ej.

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

XPath no tiene conocimiento de ninguna declaración de prefijo de espacio de nombres que se produzca en el documento de origen. Solo sabe a qué espacio de nombre (URI) pertenece cada elemento (y atributo).

+0

No ingresé todo el XML, lo siento. Es el XML exportado de la lista de reproducción de YouTube y comienza con: ' ' Yo soy el acceso a XML en PHP, por lo que he registrado yt espacio de nombres: ' registerNamespace ('yt', 'http://gdata.youtube.com/schemas/2007'); ' lo hace no funciona en el sentido de que obtengo una DOMNodeList vacía al hacer una consulta. Thnx – wurdalack

4

Ese XPath parece correcto.

Podría ser que su biblioteca no admita atributos de espacio de nombres, o que no haya registrado correctamente el espacio de nombres yt y/o el espacio de nombres media.

intente Es a juego en el local-name() y namespace-uri() en el interior de los filtros de predicados, en lugar de utilizar el espacio de nombres en el prefijo:

./*[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 

Si esto funciona, entonces hay un problema al registrar los espacios de nombres para los Namespace prefijos.

1

Suponiendo que el resto está en orden, simplemente reemplazar la primera . en el XPath con / para obtener //media:group/... (o comienzan con /atom:feed/media:group/... y registrar el espacio de nombres de átomos).

Aquí está un ejemplo de trabajo completo:

<?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); 
Cuestiones relacionadas