【问题标题】:xml parsing of a soap envelope using XmlDocument使用 XmlDocument 解析肥皂信封的 xml
【发布时间】:2017-02-04 03:16:00
【问题描述】:

我开始使用 XmlDocument 在 C# 中解析 XML。我已经关注 xml

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <soapenv:Body>
        <ns1:getCustomersResponse soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns1="http://DefaultNamespace">
            <getCustomersReturn soapenc:arrayType="soapenc:string[2]" xsi:type="soapenc:Array" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">
                <getCustomersReturn xsi:type="soapenc:string"></getCustomersReturn>
                <getCustomersReturn xsi:type="soapenc:string">some data</getCustomersReturn>
                <getCustomersReturn xsi:type="soapenc:string">some more data</getCustomersReturn>
            </getCustomersReturn>
        </ns1:getCustomersResponse>
    </soapenv:Body>
</soapenv:Envelope>

我的代码:

XmlDocument xmlDocument = new XmlDocument();
xmlDocument.LoadXml(result);  //loading soap message as string
XmlNamespaceManager xmlNamespaceManager = new XmlNamespaceManager(xmlDocument.NameTable);

xmlNamespaceManager.AddNamespace("ns1", "http://DefaultNamespace"); 

XmlNodeList xmlNodeList = xmlDocument.SelectNodes("//ns1:getCustomersResponse/getCustomersReturn", xmlNamespaceManager);

string[] results = new string[xmlNodeList.Count];

var str = "";
var count = 0;
foreach (XmlNode xmlNode in xmlNodeList)
{
    str += xmlNode.InnerText;
}

Assert.IsNull(results, xmlNodeList.Count + ", " + count + ", " + str);

我想将getCustomersReturn 的子节点(文本)检索为string[]

问题:

所有节点都被扁平化为单个字符串而不是数组。

xmlNodeList.Count 是 1 而不是 3

编辑:实施答案后的后续问题

CS1061  'XmlDocument' does not contain a definition for 'SelectNodes' and no extension method 'SelectNodes' accepting a first argument of type 'XmlDocument' could be found (are you missing a using directive or an assembly reference?)

【问题讨论】:

  • 有人可以建议或建议而不是投票,所以我知道这个问题有什么问题

标签: c# xml soap


【解决方案1】:

您的代码有一处更改。 换行:

XmlNodeList xmlNodeList = xmlDocument.SelectNodes("//ns1:getCustomersResponse/getCustomersReturn", xmlNamespaceManager);

下面一行

XmlNodeList xmlNodeList = xmlDocument.SelectNodes("//ns1:getCustomersResponse/getCustomersReturn/getCustomersReturn", xmlNamespaceManager);

使用下面的代码,它会给你想要的输出

    XmlDocument xmlDocument = new XmlDocument();
                xmlDocument.LoadXml(result);  //loading soap message as string
                XmlNamespaceManager xmlNamespaceManager = new XmlNamespaceManager(xmlDocument.NameTable);

                xmlNamespaceManager.AddNamespace("ns1", "http://DefaultNamespace");

                XmlNodeList xmlNodeList = xmlDocument.SelectNodes("//ns1:getCustomersResponse/getCustomersReturn/getCustomersReturn", xmlNamespaceManager);

                string[] results = new string[xmlNodeList.Count];

                var str = "";
                var count = 0;
                foreach (XmlNode xmlNode in xmlNodeList)
                {
                    str += xmlNode.InnerText;
                }

                Assert.IsNull(results, xmlNodeList.Count + ", " + count + ", " + str);

【讨论】:

  • 谢谢,你能解释一下为什么我不得不提到getCustomersReturn两次
  • 是的 getCustomersReturn 在您的 xml 正文中的 getCustomersReturn 内,因此需要提及两次
  • 感谢您的解释,是否可以在迭代时使用字符串数组而不是列表?感谢代码编辑。
  • xmlDocument.SelectNodes 的返回类型是 XmlNodeList 所以我们需要使用 XmlNodeList 如果您需要更多解释,请告诉我
  • 谢谢,代码可以正常工作,并且它一直在我的单元测试中工作,现在我将代码移到正在测试的库类中,我遇到了SelectNodes 错误,知道吗?我的意思是相同的代码在单元测试中运行良好,但在类文件中无法运行。
【解决方案2】:

仅使用XPath 表达式,此代码很简单,但可以帮助您了解您遇到了什么问题。这个链接可以帮助你理解XPathhttps://en.wikipedia.org/wiki/XPath

    var xml = new XmlDocument();
    xml.LoadXml(xmlstring);
    XmlNamespaceManager manager = new XmlNamespaceManager(xml.NameTable);
    manager.AddNamespace("ns1", "http://DefaultNamespace");
    //select all nodes using XPath
    var search = xml.SelectNodes("//ns1:getCustomersResponse/getCustomersReturn//getCustomersReturn",manager);
    //saving XmlNodeList to List<string>
    var r = new List<string>();
    foreach (XmlNode item in search)
        r.Add(item.InnerText);
    string[] ary = r.ToArray(); //convert List<string> to string[]

【讨论】:

  • 你能解释一下为什么getCustomersReturn被重复了两次吗?
  • XML 结构像一棵树,如果XPath 表达式是//ns1:getCustomersResponse/getCustomersReturn,那么只匹配getCustomersResponse/getCustomersReturn,但是在你的xml 文件中,getCustomersResponse 有很多getCustomersResponse 子级,所以XPath必须使用'/ns1:getCustomersResponse/getCustomersResponse//getCustomersResponse'。
  • 感谢解释,最后一个节点有两个正斜杠,有什么意义或者是错字,也可以点赞,不知道为什么大家都急于否定投票,还有迭代时是否可以使用字符串 [] 数组而不是列表,感谢代码编辑
  • 一个正斜杠表示只有一个孩子,两个正斜杠表示所有适合的孩子。这是XPath expression。但在这里,有相同的。 查看更多en.wikipedia.org/wiki/XPath
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-01-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-25
相关资源
最近更新 更多