Pregunta

Estoy intentando analizar una respuesta de un servicio web SOAP, pero parte de los datos tiene un elemento xmlns no válido y creo que me está causando un sinfín de problemas.

La parte del XML con la que estoy trabajando es la siguiente.

<soap:Body xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
    <ResponseData xmlns="http://www.example.com/WebServices/Schemas/1">
        <ResponseDataResult>
            <Messages xmlns="http://www.example.com/WebServices/Schemas/2">
                <Message>...</Message>
            </Messages>
        </ResponseDataResult>
        ...
    </ResponseData>
</soap:Body>

El URI de xmlns en el jabón: el nodo del cuerpo está bien, es el de ResponseData que no es válido, apunta a un documento inexistente. Cabe señalar que el servicio web no está bajo mi control, por lo que solucionar esto está fuera de cuestión :(.

mi código Delphi (2007) se ve, en este momento, algo como esto.

var l_tmp,l_tmp2,FSOAPBody:IXMLNode;

begin
    ...

    FSOAPBody := FSOAPEnvelope.ChildNodes.FindNode('Body','http://schemas.xmlsoap.org/soap/envelope/');
    //returns the xml above.
    if (FSOAPBody = nil) then exit;

    l_tmp := FSOAPBody.ChildNodes.FindNode('ResponseData','');
    if (l_tmp = nil) or (not l_tmp.HasChildNodes) then exit;

    l_tmp2 := l_tmp.ChildNodes.FindNode('ResponseDataResult','');

    ...
end;

En el código anterior, he tenido que agregar la url del espacio de nombres en blanco al código FindNode ('ResponseData', '') ya que sin él, no encontrará nada y devuelve nil, con ello, sin embargo, vuelve a generar el XML esperado.

El problema es que el siguiente nodo de búsqueda ( ChildNodes.FindNode ('ResponseDataResult', '') ) genera una infracción de acceso al intentar acceder a ChildNodes de l_tmp, puedo mirar el xml usando l_tmp.xml y ver que es el XML que esperaría.

Sospecho que se debe al espacio de nombres que falta, por lo que he intentado eliminarlo, pero recibo más errores diciendo que es un atributo de solo lectura.

¿Hay alguna forma de eliminar el atributo xmlns o seleccionar nodos independientemente de su NS? o voy sobre esto mal?

¿Fue útil?

Solución

No es esperado que todos los URI de espacio de nombres se refieran a recursos reales. Se usan principalmente como identificadores únicos para que XML de múltiples fuentes pueda usar los mismos nombres sin interferir entre sí. No están obligados a señalar el esquema que describe el elemento válido y los valores de atributo para el espacio de nombres; XML ni siquiera requiere que exista tal esquema.

Si desea buscar elementos sin tener en cuenta el espacio de nombres, llame a la versión de un argumento de FindNode .

l_tmp := FSOAPBody.ChildNodes.FindNode('ResponseData');

La versión de dos argumentos requiere un espacio de nombres, y cuando especifica una cadena vacía, significa que solo solicita nodos que tengan espacios de nombres vacíos. Como aparentemente sabe cuál es el espacio de nombres, podría llamar a la versión de dos argumentos de todos modos, tal como la usó para obtener el elemento del cuerpo:

l_tmp := FSOAPBody.ChildNodes.FindNode('ResponseData',
           'http://www.example.com/WebServices/Schemas/1');
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top