2009-05-06 5 views
1

J'essaie d'analyser une réponse d'un service Web SOAP, mais une partie des données contient un élément xmlns invalide et je pense que cela ne me cause aucun problème.Delphi - URI d'espace de noms non valide dans IXMLNode

La partie du fichier XML avec laquelle je travaille est la suivante.

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

Les xmlns URI dans le savon: nœud du corps est OK, son celui responseData qui est invalide, il souligne un document de ne existant. Il convient de noter que le service Web n'est pas sous mon contrôle donc la fixation de c'est hors de question :(.

mon Delphi (2007) look code, à l'heure actuelle, quelque chose comme ça.

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; 

Dans le code ci-dessus, j'ai dû ajouter l'url de l'espace de nom vide au code FindNode('ResponseData','') comme sans, il ne trouve rien et retourne zéro, mais il reutrns le code XML attendu

Le problème est que le next find node (ChildNodes.FindNode('ResponseDataResult','')) soulève une violation d'accès en essayant d'accéder aux ChildNodes de l_tmp, je peux regarder le xml en utilisant l_tmp.xml et voyez que c'est le XML auquel je m'attendrais.

Je suppose que cela est dû à l'espace de noms manquant, donc j'ai essayé de le supprimer, mais obtenir plus d'erreurs en disant qu'il s'agit d'un attribut en lecture seule.

Y at-il de toute façon pour supprimer l'attribut xmlns ou sélectionner des nœuds indépendamment de là NS? ou est-ce que je vais à propos de ce mauvais?

Répondre

2

ne s'attend pas à ce que tous les URI d'espace de noms se réfèrent à des ressources réelles. Ils sont principalement utilisés comme des identifiants uniques afin que XML provenant de plusieurs sources puissent utiliser les mêmes noms sans interférer les uns avec les autres. Ils ne sont pas tenus de pointer vers le schéma qui décrit l'élément valide et les valeurs d'attribut pour l'espace de noms; XML n'exige même pas qu'un tel schéma existe.

Si vous souhaitez rechercher des éléments sans tenir compte de l'espace de noms, appelez la version à un seul argument de FindNode.

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

La version à deux arguments nécessite un espace de noms, et lorsque vous spécifiez une chaîne vide, cela signifie que vous demandez que les nœuds qui ont namespaces vides. Puisque vous savez apparemment quel est l'espace de noms, vous pouvez appeler la version à deux arguments de la même façon, comme vous l'avez utilisé pour obtenir l'élément body:

l_tmp := FSOAPBody.ChildNodes.FindNode('ResponseData', 
      'http://www.example.com/WebServices/Schemas/1');