xml-namespaces - prefijos - xml espacio de nombre
Referencia al prefijo de espacio de nombres no declarado al analizar MSXML (3)
¿Cómo resuelvo el
Reference to undeclared namespace prefix: ''%s''
¿Problema con la implementación de MSXML de Microsoft?
Estoy usando un feed XML de un sitio web del gobierno que contiene valores que necesito analizar. El xml contiene espacios de nombres:
<?xml version="1.0" encoding="ISO-8859-1"?>
<rdf:RDF
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns="http://purl.org/rss/1.0/"
xmlns:cb="http://www.cbwiki.net/wiki/index.php/Specification_1.1"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:dcterms="http://purl.org/dc/terms/"
xmlns:xsi="http://www.w3c.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.w3c.org/1999/02/22-rdf-syntax-ns#rdf.xsd">
<item rdf:about="http://www.bankofcanada.ca/stats/rates_rss/STATIC_IEXE0101.xml">
<cb:statistics>
<cb:exchangeRate>
<cb:value decimals="4">1.0351</cb:value>
<cb:baseCurrency>CAD</cb:baseCurrency>
<cb:targetCurrency>USD</cb:targetCurrency>
<cb:rateType>Bank of Canada noon rate</cb:rateType>
<cb:observationPeriod frequency="daily">2011-05-09T12:15:00-04:00</cb:observationPeriod>
</cb:exchangeRate>
</cb:statistics>
</item>
</rdf:RDF>
Ejecutando la consulta XPath:
/rdf:RDF/item/cb:statistics/cb:exchangeRate/cb:targetCurrency
falla con el error:
Reference to undeclared namespace prefix: ''rdf''
Editar :
Si edito el XML original para eliminar todo uso de espacios de nombres:
<?xml version="1.0" encoding="ISO-8859-1"?>
<rdf>
<item>
<statistics>
<exchangeRate>
<value decimals="4">1.0351</value>
<baseCurrency>CAD</baseCurrency>
<targetCurrency>USD</targetCurrency>
<rateType>Bank of Canada noon rate</rateType>
<observationPeriod frequency="daily">2011-05-09T12:15:00-04:00</observationPeriod>
</exchangeRate>
</statistics>
</item>
</rdf>
La consulta /rdf/item/statistics/exchangeRate/baseCurrency
no falla, y devuelve nodos:
<baseCurrency>CAD</baseCurrency>
¿Cómo consigo Microsoft XML para trabajar con espacios de nombres?
Editar 2
He intentado agregar SelectionNamespaces al objeto DOMDocument:
doc.setProperty(''SelectionNamespaces'', ''xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:cb="http://www.cbwiki.net/wiki/index.php/Specification_1.1"'');
Ahora la consulta xpath no falla, pero tampoco devuelve nodos:
nodes = doc.selectNodes(''/rdf:RDF/item/cb:statistics/cb:exchangeRate/cb:targetCurrency'');
Ver también
Si está utilizando XMLSerializer
y ve este error, es probable que esté ejecutando el error de IE que se describe aquí:
https://.com/a/11399681
Me tomó mucho tiempo darme cuenta de que esto estaba sucediendo, así que pensé que era mejor vincular estos dos problemas.
Usar SelectionNamespaces
es el enfoque correcto, solo le falta un espacio de nombres.
Observe que su documento XML establece explícitamente el espacio de nombres predeterminado de la siguiente manera:
xmlns="http://purl.org/rss/1.0/"
Esto significa que cualquier elemento sin un prefijo, como el elemento item
, está en realidad en el espacio de nombres predeterminado. Entonces, si desea seleccionar ese elemento con una expresión XPath, primero debe establecer un espacio de nombres de selección apropiado.
Para hacer esto, puedes cambiar tu llamada a setProperty
así:
doc.setProperty(''SelectionNamespaces'', ''xmlns:rss="http://purl.org/rss/1.0/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:cb="http://www.cbwiki.net/wiki/index.php/Specification_1.1"'');
Aquí ha asignado el espacio de nombres predeterminado del documento al rss:
prefix en su expresión XPath. Con ese cambio en su lugar, la siguiente expresión XPath debería funcionar correctamente:
nodes = doc.selectNodes(''/rdf:RDF/rss:item/cb:statistics/cb:exchangeRate/cb:targetCurrency'');
Funciona porque hace referencia al item
elemento utilizando el espacio de nombres correcto. El hecho de que el prefijo difiera entre la expresión XPath y el documento original es irrelevante. Lo que importa es el espacio de nombres al que está vinculado el prefijo.
doc.setProperty(''SelectionNamespaces'', ''xmlns:rss="http://purl.org/rss/1.0/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:cb="http://www.cbwiki.net/wiki/index.php/Specification_1.1"'');
No olvide cargar el archivo xsd o el esquema en el objeto xmldoc
es el camino a seguir
No tengo suficiente reputación para comentar. Pero eso me ahorró mucho tiempo.
Muchas gracias