vinculado resolverse prefijo nombres lectura está espacio error definido debe como asp.net xml .net-3.5 xpath namespaces

asp.net - resolverse - XML: se afirma que un prefijo de espacio de nombres no se declara cuando es un hecho



el prefijo del espacio de nombres no está definido (2)

Sorprendentemente (para mí), este es el comportamiento predeterminado de XPath. Por defecto, los prefijos del espacio de nombres no están permitidos en una consulta XPath.

Para resolver esto, debe registrar los prefijos deseados con la propiedad SelectionNamespaces de DOMObject.

objXML.setProperty("SelectionNamespaces", "xmlns:t=''http://our.website.com/ns/''")

Después de eso, uno puede usar expresiones calificadas con t: en consultas XPath. Esto también resuelve el problema original que nos obligó a usar XmlNamespaceDeclarations en primer lugar.

Tenemos un servicio web que devuelve un XML muy simple.

<?xml version="1.0"?> <t:RequestResult xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://our.website.com/ns/" xmlns:t="http://our.website.com/ns/"> <t:Result>No candy for you today.</t:Result> <t:Success>false</t:Success> </t:RequestResult>

El que llama obtiene este XML sin problemas, usando XMLHTTP. Pero las consultas XPath no funcionan contra este XML debido a "Referencia al prefijo del espacio de nombres no declarado: ''t''"

¿Porque? Yo diría que el prefijo ''t'' está algo declarado. ¿Es este documento inválido de alguna manera?

En caso de que se pregunte por qué tuvimos que usar XmlNamespaceDeclarations para agregar prefijos de espacio de nombres , es porque de lo contrario el documento resultante no se puede consultar porque tiene un espacio de nombres de destino pero no tiene un prefijo, por lo que XPath ignora el nodo nombres porque no pertenecen al espacio de nombres solicitado (vacío), y no queremos utilizar construcciones como "//*[namespace-uri()=''http://our.website.com/ns'' and local-name()=''RequestResult'']" .


Ya has respondido la pregunta, pero vale la pena entender por qué es así.

El espacio de nombres en el que se encuentra un elemento no puede determinarse únicamente por el prefijo del espacio de nombres. Para encontrar en qué espacio de nombres está un elemento llamado t:foo , debe buscar el eje ancestro o uno mismo hasta encontrar el nodo más cercano que defina el espacio de nombres para t: Por ejemplo:

<t:one xmlns:t="ns-one"> <t:one> <t:two xmlns:t="ns-two"> <t:two/> </t:two> </t:one> </t:one>

En ese documento, cada elemento cuyo nombre es one está en el espacio de nombre ns-one , y cada elemento cuyo nombre es two está en el espacio de nombres ns-two . Se puede decir que el elemento más profundo en ese documento está en ns-two no porque t: intrínsecamente significa ns-two , sino porque si busca el eje ancestro-o-auto, el primer elemento con el que xmlns:t atributo en él - su padre - le dice el espacio de nombres.

Teniendo en cuenta que, ¿qué nodos debería coincidir con la expresión XPath //t:* ? Es imposible decirlo, porque el espacio de nombres t: se asigna a los cambios en todo el documento.

Además, los prefijos de espacio de nombres son temporales, pero los espacios de nombres son permanentes. Si sabes que one está en ns-one , realmente, realmente no te importa si su prefijo es t: o x: o si no tiene ningún prefijo y solo un atributo xmlns .

Cuando consultas un documento XML con XPath, necesitas una forma de especificar en qué espacio de nombres está un elemento dado. Y eso es lo que ocurre con SelectionNamespaces en un DOMDocument, o un gestor de espacio de nombres en C #, o lo que sea: te dicen qué espacios de nombres los prefijos en sus consultas XPath representan. Entonces, si configuré el prefijo a: en ns-one , XPath //a:one me encontrará todos los elementos nombrados one en el espacio de nombres ns-one , independientemente de cuál sea el prefijo real que estén usando en el el documento que estoy buscando es.

Esto es un poco contradictorio cuando lo estás aprendiendo por primera vez, pero en realidad, es la única forma que tiene algún sentido.