使用SelectSingleNode的foreach循环始终返回第一个节点

时间:2018-02-19 15:19:23

标签: c# xml selectsinglenode xml-documentation

我试图从httpxml响应中获取每个域节点的内部文本。 我将响应保存到字符串并加载到XmlDocument。但是使用下面的代码或其中的变体我要么得到“CorpDomainMyDomain aaaa”,要么只得到“CorpDomain aaaa”。 我尝试了域和域的各种迭代,无法单独获取域。 我原以为是

XmlNodeList elemList = xmlDoc.SelectNodes("//DAV:domains", nsmgr); 

会创建一个每个域元素的列表,但它似乎不是那样。

xml:

<?xml version="1.0" encoding="UTF-8" ?>
  <multistatus xmlns="DAV:">
   <response>

    <propstat>
        <prop>
            <domains>
                <domain logindefault="1" type="internal"><![CDATA[CorpDomain]]></domain>
                <domain type="internal"><![CDATA[MyDomain]]></domain>
            </domains>
        </prop>
    <status>HTTP/1.1 200 OK</status>
    </propstat>
</response>

我的代码段

var nsmgr = new XmlNamespaceManager(xmlDoc.NameTable);
nsmgr.AddNamespace("DAV", "DAV:");
XmlNodeList elemList = xmlDoc.SelectNodes("//DAV:domains", nsmgr);

foreach (XmlNode node in elemList)
{
  strNode = node.SelectSingleNode("//DAV:domains", nsmgr).InnerText;
  responseString = strNode+" aaaa  ";
}

return responseString;

1 个答案:

答案 0 :(得分:0)

(即使你已经修复了Ian选择的responseString += strNode问题,当你循环domain父母下的domains元素时,你就不应该&#39;再次使用// - 这会将上下文重置为文档的根目录。

e.g。如果您的XmlDocument看起来像:

<?xml version="1.0" encoding="UTF-8" ?>
  <multistatus xmlns="DAV:">
   <response>
    <propstat>
        <prop>
            <domains>
                <domain logindefault="1" type="internal">domains1-domain1</domain>
                <domain type="internal">domains1-domain2</domain>
            </domains>
        </prop>
        <prop>
            <domains>
                <domain logindefault="1" type="internal">domains2-domain1</domain>
                <domain type="internal">domains2-domain2</domain>
            </domains>
        </prop>
       <status>HTTP/1.1 200 OK</status>
    </propstat>
   </response>
</multistatus>

你的代码实际上会刮掉第一个domains元素的所有子节点的组合文本节点,例如(aaaa是你的分隔符):

  

domains1-domain1 aaaa domains1-domain2 aaaa

相反,您应该只提供从父级到子级的相对路径,即在您的情况下只是domain。假设有N domains个父元素,每个元素都有M domain子元素,如果停在父节点,则需要通过子节点进行第二级迭代:

var nsmgr = new XmlNamespaceManager(xmlDoc.NameTable);
nsmgr.AddNamespace("DAV", "DAV:");
XmlNodeList elemList = xmlDoc.SelectNodes("//DAV:domains", nsmgr);
foreach (var domains in elemList)
{
    foreach (var domain in domains.SelectNodes("DAV:domain", nsmgr))
    {
       strNode = domain.InnerText;
       responseString = strNode+" aaaa  ";
    }
}
return responseString;

但是,如果您不需要为其他目的保留对父级的引用,您也可以通过直接展平子节点来一步完成此操作。对于具有许多节点的大型xml文档,避免字符串连接问题也是一个好主意,例如:使用StringBuilder

var sb = new StringBuilder();
foreach (XmlNode node in xmlDoc.SelectNodes("//DAV:domains/DAV:domain", nsmgr))
{
    var strNode = node.InnerText;
    sb.Append(strNode); // do the same for delimiter 
}
// use sb.ToString() here.