C# 通过foreach XmlNodeList循环遍历xmlnodel?
这是我迭代xml文件的代码。通过foreach循环和IF条件检查整个XML文件中只有一个CounterSales实例,我得到了包含所有相关信息的节点 下面是代码,非常简单:C# 通过foreach XmlNodeList循环遍历xmlnodel?,c#,xml,visual-studio,visual-studio-2010,C#,Xml,Visual Studio,Visual Studio 2010,这是我迭代xml文件的代码。通过foreach循环和IF条件检查整个XML文件中只有一个CounterSales实例,我得到了包含所有相关信息的节点 下面是代码,非常简单: XmlElement root = doc.DocumentElement; XmlNodeList nodes = root.SelectNodes("//nd/ni"); foreach (XmlNode node in nodes) { if (node.OuterXml.Contains("CounterSa
XmlElement root = doc.DocumentElement;
XmlNodeList nodes = root.SelectNodes("//nd/ni");
foreach (XmlNode node in nodes)
{
if (node.OuterXml.Contains("CounterSales"))
{
// I'm in the correct node. Iterate through this node. How?
}
}
现在我已经在这里了,我需要遍历节点。当IF语句为true时,此特定节点的node.OuterXml就是这样的:
<ni>
<nss>20150927</nss>
<gp>Addon</gp>
<ns>CounterBlah1</ns>
<ns>CounterBlah2</ns>
<ns>CounterSales</ns>
<ns>CounterBlah4</ns>
<ns>CounterBlah5</ns>
<ns>CounterBlah6</ns>
<nv>
<nad>Style=1,Rfu=1,Id=132</nad>
<r>0</r>
<r>15</r>
<r>8</r>
<r>3</r>
<r>2</r>
<r>2</r>
</nv>
<nv>
<nad>Style=1,Rfu=1,Id=433</nad>
<r>0</r>
<r>15</r>
<r>30</r>
<r>3</r>
<r>2</r>
<r>2</r>
</nv>
<nv>
<nad>Style=1,Rfu=1,Id=665</nad>
<r>0</r>
<r>15</r>
<r>90</r>
<r>3</r>
<r>2</r>
<r>2</r>
</nv>
</ni>
目前,我假设第三个值是我感兴趣的值。将来,我应该数一数在哪里进行反销售,并读取相应的数字,但现在没有必要这样做
再次感谢。这里有一种方法可以让你做到这一点。其思想是迭代所有节点,用值CounterSales确定节点的索引。然后,我们使用该索引来选择相关的 我还更改了选择首字母的方式。按照您的方式,OuterXml中任何位置出现的值CounterSales都可能会提供错误匹配。这种方法使用包含谓词的XPath表达式
XmlElement root = doc.DocumentElement;
// Use XPath to find <ni> that contain CounterSales, rather than use string comparison
XmlNodeList nodes = root.SelectNodes("//nd/ni[ns='CounterSales']");
foreach (XmlNode node in nodes)
{
XmlNodeList nsNodes = node.SelectNodes("ns");
// Get index of "CountersSales" within <ni>
int index = 0;
while (index < nsNodes.Count)
{
if (nsNodes[index].InnerText == "CounterSales")
break;
index++;
}
// Search through <nv>
XmlNodeList nvNodes = node.SelectNodes("nv");
foreach (XmlElement nvNode in nvNodes)
{
XmlNode nadNode = nvNode.SelectSingleNode("nad");
// Get the stuff after the last equals sign. Possibly use regex here instead.
string id = nadNode.InnerText.Substring(nadNode.InnerText.LastIndexOf('=') + 1);
// XPathQuery for r element at our index (position in xpath is 1-based, rather than 0-based like C#)
string rQuery = String.Format("r[position() = {0}]", index + 1);
XmlNode rNode = nvNode.SelectSingleNode(rQuery);
Console.WriteLine("{0}, {1}", id, rNode.InnerText);
}
}
在linq中使用辅助函数使代码非常简单
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using System.Text.RegularExpressions;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
string input =
"<ni>" +
"<nss>20150927</nss>" +
"<gp>Addon</gp>" +
"<ns>CounterBlah1</ns>" +
"<ns>CounterBlah2</ns>" +
"<ns>CounterSales</ns>" +
"<ns>CounterBlah4</ns>" +
"<ns>CounterBlah5</ns>" +
"<ns>CounterBlah6</ns>" +
"<nv>" +
"<nad>Style=1,Rfu=1,Id=132</nad>" +
"<r>0</r>" +
"<r>15</r>" +
"<r>8</r>" +
"<r>3</r>" +
"<r>2</r>" +
"<r>2</r>" +
"</nv>" +
"<nv>" +
"<nad>Style=1,Rfu=1,Id=433</nad>" +
"<r>0</r>" +
"<r>15</r>" +
"<r>30</r>" +
"<r>3</r>" +
"<r>2</r>" +
"<r>2</r>" +
"</nv>" +
"<nv>" +
"<nad>Style=1,Rfu=1,Id=665</nad>" +
"<r>0</r>" +
"<r>15</r>" +
"<r>90</r>" +
"<r>3</r>" +
"<r>2</r>" +
"<r>2</r>" +
"</nv>" +
"</ni>";
XElement ni = XElement.Parse(input);
var results1 = ni.Descendants("nv").Select(x => new
{
nad = x.Element("nad").Value,
r = x.Elements("r").Select(y => y.Value).ToList()
}).ToList();
var results2 = results1.Select(x => new {
Id = Helper(x.nad, "Id"),
r = int.Parse(x.r[2])
}).ToList();
}
static int? Helper(string csv, string name)
{
int? results = null;
string pattern = @"(?'name'\w+)=(?'value'\d+)";
MatchCollection matches = Regex.Matches(csv, pattern);
foreach(Match match in matches)
{
string csvName = match.Groups["name"].Value;
if(csvName == name)
{
results = int.Parse(match.Groups["value"].Value);
break;
}
}
return results;
}
}
}
您必须使用XmlNodeList等吗?使用LINQ到XML几乎所有事情都更简单:您可能是对的;迟早我会处理好的。但调试和断点似乎有点困难,因为很多事情都是用很少的代码完成的。。。我想XML格式本身无法更改?我认为这是一种非常糟糕的格式。。。使用当前格式是可行的,但并不有趣。但现在正是学习的好时机,因此我将使用linq to xml进行测试。我希望可以更改格式,但不幸的是,这实际上是不可能的。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using System.Text.RegularExpressions;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
string input =
"<ni>" +
"<nss>20150927</nss>" +
"<gp>Addon</gp>" +
"<ns>CounterBlah1</ns>" +
"<ns>CounterBlah2</ns>" +
"<ns>CounterSales</ns>" +
"<ns>CounterBlah4</ns>" +
"<ns>CounterBlah5</ns>" +
"<ns>CounterBlah6</ns>" +
"<nv>" +
"<nad>Style=1,Rfu=1,Id=132</nad>" +
"<r>0</r>" +
"<r>15</r>" +
"<r>8</r>" +
"<r>3</r>" +
"<r>2</r>" +
"<r>2</r>" +
"</nv>" +
"<nv>" +
"<nad>Style=1,Rfu=1,Id=433</nad>" +
"<r>0</r>" +
"<r>15</r>" +
"<r>30</r>" +
"<r>3</r>" +
"<r>2</r>" +
"<r>2</r>" +
"</nv>" +
"<nv>" +
"<nad>Style=1,Rfu=1,Id=665</nad>" +
"<r>0</r>" +
"<r>15</r>" +
"<r>90</r>" +
"<r>3</r>" +
"<r>2</r>" +
"<r>2</r>" +
"</nv>" +
"</ni>";
XElement ni = XElement.Parse(input);
var results1 = ni.Descendants("nv").Select(x => new
{
nad = x.Element("nad").Value,
r = x.Elements("r").Select(y => y.Value).ToList()
}).ToList();
var results2 = results1.Select(x => new {
Id = Helper(x.nad, "Id"),
r = int.Parse(x.r[2])
}).ToList();
}
static int? Helper(string csv, string name)
{
int? results = null;
string pattern = @"(?'name'\w+)=(?'value'\d+)";
MatchCollection matches = Regex.Matches(csv, pattern);
foreach(Match match in matches)
{
string csvName = match.Groups["name"].Value;
if(csvName == name)
{
results = int.Parse(match.Groups["value"].Value);
break;
}
}
return results;
}
}
}