简体   繁体   English

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

[英]foreach loop with SelectSingleNode always returns the first node

I am trying to get the inner text of each domain node from an httpxml response. 我试图从httpxml响应中获取每个域节点的内部文本。 I save the response to a string and load to XmlDocument . 我将响应保存到字符串中并加载到XmlDocument But using the code below or variations of it I either get "CorpDomainMyDomain aaaa" or just "CorpDomain aaaa". 但是,使用下面的代码或其变体,我会得到“ CorpDomainMyDomain aaaa”或仅仅是“ CorpDomain aaaa”。 I have tried various iterations of domain and domains and cannot get the domains individually. 我尝试了域和域的各种迭代,但无法单独获取域。 I would have thought that 我本以为

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

would have created a list of each of the Domain elements but it doesn't seem that way. 本来会创建每个Domain元素的列表,但事实并非如此。

The xml: 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>

My code snippet 我的代码段

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;

(Even after you've fixed the responseString += strNode issue that Ian picked up on, When you loop through the domain elements under the domains parent, you shouldn't again use // - that will reset the context to the root of the document. (即使在解决了Ian遇到的responseString += strNode问题之后,当您遍历domainsdomain下的domain元素时,也不应再次使用// -会将上下文重置为文献。

eg if your XmlDocument looks like: 例如,如果您的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>

your code would in fact scrape the combined text nodes of all child nodes of just the first domains element, ie something like (where aaaa is your delimiter): 实际上,您的代码会抓取仅第一个domains元素的所有子节点的组合文本节点,即类似(其中aaaa是您的定界符)的内容:

domains1-domain1 aaaa domains1-domain2 aaaa domains1-domain1 aaaa domains1-domain2 aaaa

Instead, you should just provide the relative pathing from parent to child, ie just domain in your case. 相反,您应该只提供从父级到子级的相对路径,即您所涉及的domain Assuming that there are N domains parent elements each with M domain child elements, if you stop at the parent nodes, you will need a second level of iteration through the child nodes: 假设有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;

But if you don't need to retain a reference to the parent for other purposes, you could also do this in one step by flattening out the child nodes directly. 但是,如果您不需要为其他目的保留对父级的引用,也可以通过直接展平子节点一步来实现。 For large xml documents with many nodes, it would also be a good idea to avoid the string concatenation problem, eg with a StringBuilder : 对于具有许多节点的大型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.

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM