C# 从 SOAP 消息中提取 SOAP 正文
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10294544/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Extract SOAP body from a SOAP message
提问by CrBruno
I want to extract SOAP body from a SOAP message, I have some data in SOAP body that I have to parse in date base, so this is the code:
我想从 SOAP 消息中提取 SOAP 主体,我在 SOAP 主体中有一些数据,我必须在日期库中解析,所以这是代码:
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);
}
I got an error here:
我在这里遇到错误:
int iSoapBodyElementStartEnd = SoapMessage.IndexOf(">", iSoapBodyElementStartFrom);
The error:
错误:
Index was out of range. Must be non-negative and less than the size of the collection.
指数超出范围。必须是非负的并且小于集合的大小。
If anyone knows how to solve this?
如果有人知道如何解决这个问题?
采纳答案by Luis Quijada
For a request like this:
对于这样的请求:
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>";
The following code did the work to unwrap the data and get only the <ReponseData>xml content:
以下代码完成了解包数据并仅获取<ReponseData>xml 内容的工作:
XDocument xDoc = XDocument.Load(new StringReader(request));
var unwrappedResponse = xDoc.Descendants((XNamespace)"http://schemas.xmlsoap.org/soap/envelope/" + "Body")
.First()
.FirstNode
回答by L.B
Linq2Xml is simpler to use.
Linq2Xml 使用起来更简单。
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--
- 编辑 -
To loop elements in body:
在 中循环元素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);
}
回答by Rich Hildebrand
You can utilize GetElementsByTagNameto extract the body of the soap request.
您可以利用GetElementsByTagName来提取肥皂请求的正文。
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);
}
}
回答by Gywerd
Simple solution, if body has multiple children, and you just wat to remove envelope:
简单的解决方案,如果 body 有多个孩子,而你只是想删除信封:
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(placeYourXmlHere);
if (xmlDoc.DocumentElement.Name == "soapenv_Envelope")
{
string tempXmlString = xmlDoc.DocumentElement.InnerXml;
xmlDoc.LoadXml(tempXmlString);
}
If you want to remove both Envelope and body, where body only contain one child:
如果要同时删除 Envelope 和 body,其中 body 仅包含一个子项:
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(placeYourXmlHere);
while (xmlDoc.DocumentElement.Name == "soapenv_Envelope" || xmlDoc.DocumentElement.Name == "soapenv_Body")
{
string tempXmlString = xmlDoc.DocumentElement.InnerXml;
xmlDoc.LoadXml(tempXmlString);
}
Now the xml is reduced to the content of the Body
现在 xml 减少到 Body 的内容

