2012-04-24 25 views
11

Ich möchte SOAP-Body aus einer SOAP-Nachricht extrahieren, ich habe einige Daten in SOAP-Körper, die ich habe Datum Basis zu analysieren, so ist dies der Code:Extract SOAP-Body aus einer SOAP-Nachricht

public string Load_XML(string SoapMessage) 
{ 
    //check soap message 
    if (SoapMessage == null || SoapMessage.Length <= 0) 
     throw new Exception("Soap message not valid"); 

    //declare some local variable 
    int iSoapBodyStartIndex = 0; 
    int iSoapBodyEndIndex = 0; 

    //load the Soap Message 
    //Učitaj string XML-a i pretvori ga u XML 
    XmlDocument doc = new XmlDocument(); 

    try 
    { 
     doc.Load(SoapMessage); 
    } 

    catch (XmlException ex) 
    { 
     WriteErrors.WriteToLogFile("WS.LOAD_DOK_LoadXML", ex.ToString()); 

     throw ex; 
    } 

    //search for the "http://schemas.xmlsoap.org/soap/envelope/" URI prefix 
    string prefix = string.Empty; 
    for (int i = 0; i < doc.ChildNodes.Count; i++) 
    { 
     System.Xml.XmlNode soapNode = doc.ChildNodes[i]; 
     prefix = soapNode.GetPrefixOfNamespace("http://schemas.xmlsoap.org /soap/envelope/"); 

     if (prefix != null && prefix.Length > 0) 
      break; 
    } 

    //prefix not founded. 
    if (prefix == null || prefix.Length <= 0) 
     throw new Exception("Can't found the soap envelope prefix"); 

    //find soap body start index 
    int iSoapBodyElementStartFrom = SoapMessage.IndexOf("<" + prefix + ":Body"); 
    int iSoapBodyElementStartEnd = SoapMessage.IndexOf(">", iSoapBodyElementStartFrom); -> HERE I HAVE AN ERROR!!!! 
    iSoapBodyStartIndex = iSoapBodyElementStartEnd + 1; 

    //find soap body end index 
    iSoapBodyEndIndex = SoapMessage.IndexOf("</" + prefix + ":Body>") - 1; 

    //get soap body (xml data) 
    return SoapMessage.Substring(iSoapBodyStartIndex, iSoapBodyEndIndex - iSoapBodyStartIndex + 1); 
} 

ich habe hier einen Fehler:

int iSoapBodyElementStartEnd = SoapMessage.IndexOf(">", iSoapBodyElementStartFrom); 

Der Fehler:

Index was out of range. Must be non-negative and less than the size of the collection.

Wenn jemand weiß, wie diese zu lösen?

+0

Ist es definitiv nicht negativ? Ich denke, es ist -1, weil der Startblock in der Zeichenfolge nicht übereinstimmt. Was ist in der Zeichenfolge? – Rup

+0

Ich würde auch prüfen, ob 'prefix' richtig gelesen wird. Ihr SOAP-Namespace sollte keine Leerzeichen in der Mitte haben. Werden diese Hilfe entfernt? Es kann auch besser sein, hier einen korrekten XML-Parser zu verwenden als einen Teilstring-Vergleich. – Rup

+0

Was meinst du mit richtigem XML-Parser? Ich folge dir nicht? Das möchte ich lesen CrBruno

Antwort

10

Für eine Anfrage wie folgt aus:

String request = @"<?xml version=""1.0"" encoding=""UTF-8""?> 
    <soap:Envelope xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" 
    xmlns:soapenc=""http://schemas.xmlsoap.org/soap/encoding/"" 
    xmlns:xsd=""http://www.w3.org/2001/XMLSchema"" 
    xmlns:soap=""http://schemas.xmlsoap.org/soap/envelope/""> 
    <soap:Body> 
    <ResponseData xmlns=""urn:Custom"">some data</ResponseData> 
    </soap:Body> 
    </soap:Envelope>"; 

Der folgende Code die Arbeit tat um die Daten auszupacken und nur die <ReponseData> xml zu bekommen Inhalt:

XDocument xDoc = XDocument.Load(new StringReader(request)); 

var unwrappedResponse = xDoc.Descendants((XNamespace)"http://schemas.xmlsoap.org/soap/envelope/" + "Body") 
    .First() 
    .FirstNode 
8

Linq2Xml ist einfacher zu bedienen.

string xml = @"<?xml version=""1.0"" encoding=""UTF-8"" ?> 
    <soap:envelope xmlns:xsd=""w3.org/2001/XMLSchema"" xmlns:xsi=""w3.org/2001/XMLSchema-instance"" xmlns:soap=""schemas.xmlsoap.org/soap/envelope/"">; 
    <soap:body> 
    <order> <id>1234</id> </order> 
    </soap:body> 
    </soap:envelope>"; 

XDocument xDoc = XDocument.Load(new StringReader(xml)); 
var id = xDoc.Descendants("id").First().Value; 

--EDIT--

Um Schleifenelemente in body:

XDocument xDoc = XDocument.Load(new StringReader(xml)); 
XNamespace soap = XNamespace.Get("schemas.xmlsoap.org/soap/envelope/"); 

var items = xDoc.Descendants(soap+"body").Elements(); 
foreach (var item in items) 
{ 
    Console.WriteLine(item.Name.LocalName); 
} 
+0

O danke, nur eine kleine Frage, wenn ich alle Elemente im Körpersegment extrahieren möchte, nicht nur zuerst und zuletzt, wie schreibe ich es? – CrBruno

+1

@Bruno Ich habe die Antwort bearbeitet. –

1

Sie können GetElementsByTagName verwenden, um den Körper der Seife Anfrage zu extrahieren.

private static T DeserializeInnerSoapObject<T>(string soapResponse) 
{ 
    XmlDocument xmlDocument = new XmlDocument(); 
    xmlDocument.LoadXml(soapResponse); 

    var soapBody = xmlDocument.GetElementsByTagName("soap:Body")[0]; 
    string innerObject = soapBody.InnerXml; 

    XmlSerializer deserializer = new XmlSerializer(typeof(T)); 

    using (StringReader reader = new StringReader(innerObject)) 
    { 
     return (T)deserializer.Deserialize(reader); 
    } 
} 
Verwandte Themen