Pergunta

Eu estou tentando analisar uma resposta de um serviço web SOAP, mas parte dos dados tem um elemento xmlns inválido e eu acho que está me causando um problema sem fim.

A parte do XML que eu estou trabalhando com é a seguinte.

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

Os xmlns URI no sabão: nó corpo é OK, é o um em responseData que é inválido, ele aponta para um documento existente nenhum. Deve-se notar que o serviço web não está sob meu controle para fixar isso está fora de questão:. (

minha Delphi (2007) Código do olhar, no momento, algo como isto.

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;

No código acima, eu tive que adicionar o URL namespace em branco para o código FindNode('ResponseData','') como sem ele, não vai encontrar nada e retorna nil, com ele no entanto, reutrns o XML esperado.

O problema é que o nó próximo find (ChildNodes.FindNode('ResponseDataResult','')) levanta uma violação de acesso ao tentar acessar os ChildNodes de l_tmp, eu posso olhar para o xml usando l_tmp.xml e ver que ele é o XML que eu esperaria.

Eu suspeito que isso é devido ao namespace faltando, então eu tentei removê-lo, mas obter mais erros dizendo que é um atributo somente leitura.

Existe uma maneira de remover o atributo xmlns ou selecionar nós, independentemente de haver NS? ou eu vou sobre esta errado?

Foi útil?

Solução

É não se espera que todos os URIs do namespace referem a recursos reais. Eles são usados ??principalmente como identificadores únicos de modo XML a partir de várias fontes podem usar os mesmos nomes, sem interferir uns com os outros. Eles não são necessários para apontar para o esquema que descreve os valores de elementos e atributos válidos para o namespace; XML nem sequer exigem que as houver esquema a.

Se você quiser procurar por elementos sem levar em conta namespace, em seguida, chamar a versão de um argumento de FindNode.

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

A versão de dois argumentos requer um espaço de nomes, e quando você especificar uma cadeia vazia, isso significa que você está solicitando apenas nós que têm namespaces vazios. Desde que você parece saber o que o namespace seja, você poderia chamar a versão de dois argumentos de qualquer maneira, assim como você usou para obter o elemento do corpo:

l_tmp := FSOAPBody.ChildNodes.FindNode('ResponseData',
           'http://www.example.com/WebServices/Schemas/1');
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top