使用 C# 和 XDocument/XElement 解析 Soap 响应

Posted

技术标签:

【中文标题】使用 C# 和 XDocument/XElement 解析 Soap 响应【英文标题】:Using C# and XDocument/XElement to parse a Soap Response 【发布时间】:2010-10-21 06:24:45 【问题描述】:

这是来自我的 SuperDuperService 的示例肥皂响应:

<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>
        <MyResponse xmlns="http://mycrazyservice.com/SuperDuperService">
            <Result>32347</Result> 
        </MyResponse>
    </soap:Body>
</soap:Envelope>

由于某种原因,当我尝试获取“结果”的后代或元素时,我得到了 null。它与命名空间有关吗?有人可以提供一个解决方案来从中检索 Result 吗?

【问题讨论】:

【参考方案1】:

你可能想尝试这样的事情:

string myNamespace= "http://mycrazyservice.com/SuperDuperService";

var results = from result in yourXml.Descendants(XName.Get("MyResponse", myNamespace))
              select result.Element("Result").value

这台笔记本电脑上没有 VS,所以我无法仔细检查我的代码,但它应该使用 LINQ to SQL 为您指明正确的方向。

【讨论】:

【参考方案2】:

用经过测试的代码扩展贾斯汀的答案,返回一个布尔值,响应和结果以方法名称开头(顺便说一句,甚至认为 XML 元素在解析时没有显示它需要的 NS) :

    private string ParseXml(string sXml, string sNs, string sMethod, out bool br)
    
        br = false;
        string sr = "";
        try
        
            XDocument xd = XDocument.Parse(sXml);

            if (xd.Root != null)
            
                XNamespace xmlns = sNs;
                var results = from result in xd.Descendants(xmlns + sMethod + "Response")
                              let xElement = result.Element(xmlns + sMethod + "Result")
                              where xElement != null
                              select xElement.Value;
                foreach (var item in results)
                    sr = item;
                br = (sr.Equals("true"));
                return sr;
            
            return "Invalid XML " + Environment.NewLine + sXml;
        
        catch (Exception ex)
        
            return "Invalid XML " + Environment.NewLine + ex.Message + Environment.NewLine + sXml;
        
    

【讨论】:

XDocument 不包含“解析”的定义 System.Xml.Linq.XDocument.Parse 确实存在于程序集中:System.Xml.Linq, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089【参考方案3】:

可能是这样的:

IEnumerable<XElement> list = doc.Document.Descendants("Result");
if (list.Count() > 0)

    // do stuff

【讨论】:

由于某种原因,您上面示例中的 list.Count() 方法对我来说不存在??我正在使用 VS2010 .net 4.【参考方案4】:

你的搜索方向是对的,它肯定与命名空间有关。

下面的代码返回为命名空间和元素名称的组合找到的第一个元素。

XDocument doc = XDocument.Load(@"c:\temp\file.xml");
XNamespace ns = @"http://mycrazyservice.com/SuperDuperService";
XElement el = doc.Elements().DescendantsAndSelf().FirstOrDefault( e => e.Name == ns + "Result");

【讨论】:

得到错误 - 不能在此范围内声明名为“e”的局部变量,因为它会给“e”赋予不同的含义,它已在“父或当前”范围中用于表示此解决方案的其他错误。我该如何解决这个问题【参考方案5】:

你可以试试这个。

Regex regex = new Regex("<Result>(.*)</Result>");
                var v = regex.Match(yourResponse);
                string s = v.Groups[1].ToString();

【讨论】:

以上是关于使用 C# 和 XDocument/XElement 解析 Soap 响应的主要内容,如果未能解决你的问题,请参考以下文章

[C#] C# 知识回顾 - Excetion 异常的介绍使用和处理

C# 使用 MySql 和 MariaDB

如何在 C# 和 C++ 代码之间共享常量?

C# 和 Flash 集成

如何使用命名管道通信 C 和 C# 程序

使用 Raycast 和 hitObject 编写脚本(使用 C#)