foreach 循环与 SelectSingleNode 总是 returns 第一个节点
foreach loop with SelectSingleNode always returns the first node
我正在尝试从 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;
(即使在您解决了 Ian 发现的 responseString += strNode
问题之后,当您遍历 domains
parent 下的 domain
元素时,您不应再次使用 //
- 这会将上下文重置为文档的根目录。
例如如果您的 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
元素的所有 child 节点的组合文本节点,即类似于(其中 aaaa
是您的分隔符):
domains1-domain1 aaaa domains1-domain2 aaaa
相反,您应该只提供从 parent 到 child 的相对路径,即在您的情况下只是 domain
。假设有 N domains
parent 个元素,每个元素有 M domain
child 个元素,如果你停在 parent 个节点,你将需要第二层通过 child 个节点的迭代:
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;
但是如果您不需要为其他目的保留对 parent 的引用,您也可以通过直接展平 child 节点来一步完成。对于具有许多节点的大型 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.
我正在尝试从 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;
(即使在您解决了 Ian 发现的 responseString += strNode
问题之后,当您遍历 domains
parent 下的 domain
元素时,您不应再次使用 //
- 这会将上下文重置为文档的根目录。
例如如果您的 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
元素的所有 child 节点的组合文本节点,即类似于(其中 aaaa
是您的分隔符):
domains1-domain1 aaaa domains1-domain2 aaaa
相反,您应该只提供从 parent 到 child 的相对路径,即在您的情况下只是 domain
。假设有 N domains
parent 个元素,每个元素有 M domain
child 个元素,如果你停在 parent 个节点,你将需要第二层通过 child 个节点的迭代:
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;
但是如果您不需要为其他目的保留对 parent 的引用,您也可以通过直接展平 child 节点来一步完成。对于具有许多节点的大型 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.