2008-12-09 18 views
12

Algo extraño sucedió después de que un proveedor cambió el encabezado XML un poco. Yo solía ser capaz de leer cosas usando XPath, pero ahora no puedo incluso conseguir una respuesta conPHP simplexml: ¿por qué xpath deja de funcionar?

$xml->xpath('/'); 

Lo cambiaron de esta ...

<?xml version="1.0" encoding="iso-8859-1"?> 
<!DOCTYPE NewsML SYSTEM "http://www.newsml.org/dl.php?fn=NewsML/1.2/specification/NewsML_1.2.dtd" [ 
<!ENTITY % nitf SYSTEM "http://www.nitf.org/IPTC/NITF/3.4/specification/dtd/nitf-3-4.dtd"> 
%nitf; 
]> 
<NewsML> 
... 

a esto:

<?xml version="1.0" encoding="iso-8859-1"?> 
<NewsML 
    xmlns="http://iptc.org/std/NewsML/2003-10-10/" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://iptc.org/std/NewsML/2003-10-10/ http://www.iptc.org/std/NewsML/1.2/specification/NewsML_1.2.xsd http://iptc.org/std/NITF/2006-10-18/ http://contentdienst.pressetext.com/misc/nitf-3-4.xsd" 
> 
... 

Respuesta

25

Lo más probable es que esto se deba a que han introducido un espacio de nombre predeterminado (xmlns="http://iptc.org/std/NewsML/2003-10-10/") en su documento. El soporte de SimpleXML para espacios de nombres predeterminados no es muy bueno, por decirlo suavemente.

¿Se puede tratar de registrar explícitamente un prefijo de espacio de nombres:

$xml->registerXPathNamespace("n", "http://iptc.org/std/NewsML/2003-10-10/"); 
$xml->xpath('/n:NewsML'); 

Usted tendría que adaptar sus expresiones XPath para utilizar el prefijo "n:" en cada elemento. Aquí hay información adicional: http://people.ischool.berkeley.edu/~felix/xml/php-and-xmlns.html.

EDIT: Según the spec:

The registerXPathNamespace() function crea un contexto prefijo/ns para la siguiente petición XPath.

Esto significa que tendría que ser llamado antes de cada consulta XPath, pues, una función para envolver las consultas XPath sería lo más natural que hacer:

function simplexml_xpath_ns($element, $xpath, $xmlns) 
{ 
    foreach ($xmlns as $prefix_uri) 
    { 
     list($prefix, $uri) = explode("=", $prefix_uri, 2); 
     $element->registerXPathNamespace($prefix, $uri); 
    } 
    return $element->xpath($xpath); 
} 

Uso:

$xmlns = ["n=http://iptc.org/std/NewsML/2003-10-10/"]; 
$result = simplexml_xpath_ns($xml, '/n:NewsML', $xmlns); 
+1

Gracias ¡un manojo! Además, parece que tienes que registrar los espacios de nombres antes de cada solicitud de xpath ... si pudieras agregar esto a tu respuesta, sería perfecto;) –

+0

Agregado, gracias. :) – Tomalak

+0

Gracias ... que corrigió mis consultas XPATH de mi archivo Google Earth (KML). Lo cual solo funcionaría si eliminé el atributo xmlns de mi archivo XML. –

Cuestiones relacionadas