Si tu connais le nom de <Corps_de_la_réponse> et qu'il ne change JAMAIS !
tu peux faire l'extraction très simplement
XML := Copy(ChaineSOAP, Pos(ChaineSOAP, '<Corps_de_la_réponse>') + Length('<Corps_de_la_réponse>'), Pos(ChaineSOAP, '</Corps_de_la_réponse>') - (Pos(ChaineSOAP, '<Corps_de_la_réponse>') + Length(<Corps_de_la_réponse>)));
Je te laisse corriger les +1 ou -1 pour avoir le bon nombre de caractères dans le 3eme paramètre
Bon, je suppose que ce n'est pas aussi simple dans ton cas,
sinon tu aurais trouvé cette solution évidente tout seul !
As-tu essayé ceci en chargeant tout le document ?
1 2 3 4 5 6 7
| <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<Noeud1>
<Noeud2 Attr1="Même pas mal">Trop Facile</Noeud2>
</Noeud1>
</soap:Body>
</soap:Envelope> |
ShowMessage(XMLDocument1.ChildNodes['soap:Envelope'].ChildNodes['soap:Body'].ChildNodes[0].ChildNodes[0].Text);
Mais cela aussi c'est tellement évident que cela doit être plus compliqué
Personnellement, je trouve que la syntaxe ChildNodes[...].ChildNodes[...].ChildNodes[...].ChildNodes[...].ChildNodes[...]... est horrible !
XPATH c'est chiant genre /*[local-name()="Envelope"]/*[local-name()="Body"]/*[local-name()="Noeud1"]/*[local-name()="Noeud2"
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| var
DomNodeSelectIntf: IDomNodeSelect;
DomNode: IDOMNode;
DomNodeEx: IDOMNodeEx;
begin
XMLDocument1.XML := Memo1.Lines;
XMLDocument1.Active := True;
// - Via IDomNodeSelect.selectNode
if Assigned(XMLDocument1.DOMDocument) and Supports(XMLDocument1.DOMDocument, IDomNodeSelect, DomNodeSelectIntf) then
begin
DomNode := DomNodeSelectIntf.selectNode('/*[local-name()="Envelope"]/*[local-name()="Body"]/*[local-name()="Noeud1"]/*[local-name()="Noeud2"]');
if Supports(DomNode, IDOMNodeEx, DomNodeEx) then
begin
ShowMessage('IDomNodeSelect.selectNode'
+ sLineBreak + 'Node : ' + DomNode.nodeName
+ sLineBreak + 'Text : ' + DomNodeEx.Text
+ sLineBreak + 'Attr1 : ' + DomNode.attributes.getNamedItem('Attr1').nodeValue);
end
else
begin
ShowMessage('IDomNodeSelect.selectNode'
+ sLineBreak + 'Node : ' + DomNode.nodeName
+ sLineBreak + 'Attr1 : ' + DomNode.attributes.getNamedItem('Attr1').nodeValue);
end;
end;
end; |
XPATH c'est standard mais c'est pas très facile à lire
Donc je me suis fait ma routine pour la lisibilité
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
|
function FindNodeEx(ANode: IXMLNode; const APath: array of string; APathIndex: Integer = 0): IXMLNode;
var
I: Integer;
begin
if APathIndex < High(APath) then
begin
for I := 0 to ANode.ChildNodes.Count - 1 do
begin
if SameText(ANode.ChildNodes[I].NodeName, APath[APathIndex]) then
Exit(FindNodeEx(ANode.ChildNodes[I], APath, APathIndex + 1));
end;
end
else if APathIndex = High(APath) then
begin
for I := 0 to ANode.ChildNodes.Count - 1 do
begin
if SameText(ANode.ChildNodes[I].NodeName, APath[APathIndex]) then
Exit(ANode.ChildNodes[I]);
end;
end
else if SameText(ANode.NodeName, APath[APathIndex]) then
Exit(ANode);
Result := nil;
end; |
cela permet un appel très lisible, Memo1 contient le XML ci-dessus
1 2 3 4 5 6 7 8 9 10 11 12 13
| var
XMLNode: IXMLNode;
begin
XMLDocument1.XML := Memo1.Lines;
XMLDocument1.Active := True;
// - Via FindNodeEx
XMLNode := FindNodeEx(XMLDocument1.Node, ['soap:Envelope', 'soap:Body', 'Noeud1', 'Noeud2']);
ShowMessage('FindNodeEx'
+ sLineBreak + 'Node : ' + XMLNode.NodeName
+ sLineBreak + 'Text : ' + XMLNode.Text
+ sLineBreak + 'Attr1 : ' + XMLNode.Attributes['Attr1']);
end; |
A l'époque de D6 et D7, j'ai intégré plus de 5 WebService en tant que client (j'en étais l'auteur en PHP4-NuSOAP pour certains) , j'ai toujours utilisé le WSDL !
Pourquoi ne pas utiliser ce qui existe ?
Une contrainte imposée dans votre devoir pour l'école de manipuler le XML à la main ?
Une seule fois, j'ai du le faire via un TXMLData issu d'un WS en Microsoft BizTalk, le leader peut toujours faire du non-standard que cela en devient un standard quelques années plus tard
Mais même dans ce cas, je suis passé par le WSDL pour me créer un objet TRemotable qui s'occupe d'extraire le simple XML à partir du message SOAP
Plus fiable que le Copy si ton contenu évolue !
As-tu essayer d'utiliser le TXMLData pour extraire le XML dans le SOAP ?
Au final, le TXMLData ne contiendra QUE le XML de données dans sa propriété TXMLData.XMLNode ce qui résoud ton problème de l'enveloppe SOAP
Et ce qui est merveilleux lorsque l'on utilise ce qui existe, c'est que XMLNode c'est un IXMLNode qui propose la propriété TXMLData.XMLNode.ChildNodes
Tu as une version XE7, TXMLData est inclus ! Profites-en !
En Delphi 7, il y a plus de 10 ans, cela n'étais pas le cas, il a fallu que je cherche
Au final tu pourrais écrire en utilisant le WSDL et le générateur de code source
ShowMessage((THTTPRIO as IMonService).GetXML().XMLData.XMLNode.ChildNodes['Noeud1'].ChildNodes['Noeud2'].Text);
Faut-il écouter les conseils des développeurs expérimentés lorsque l'on est un étudiant !
Partager