这是我遍历xml文件的代码。使用foreach循环和IF条件检查整个XML文件中“CounterSales”的唯一一个实例,我得到包含所有相关信息的节点。
这是代码,非常简单:
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?
}
}
既然我已经在这里,我需要遍历node
。当node.OuterXml
语句为真时,这就是此特定节点的IF
:
<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
是第3个节点,这意味着我需要在每个<nad>
中获取ID,然后获取每个<r>
的第3个值。
最终结果将是:
132, 8
433, 30
665, 90
目前,我假设第3个<r>
值是我感兴趣的值。将来,我应该计算 where <ns>CounterSales</ns>
并阅读适当的数字,但现在不需要。
再次感谢。
答案 0 :(得分:0)
这是你可以做到的一种方式。我们的想法是迭代所有<ns>
节点,以确定具有值&#34; CounterSales&#34;的节点的索引。然后,我们使用该索引选择相关的<r>
。
我还更改了选择初始<ni>
的方式。你拥有它的方式,价值&#34; CounterSales&#34;出现在OuterXml中的任何地方都可能会给你一个错误的匹配。这种方式使用包含谓词的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);
}
}
答案 1 :(得分:0)
使用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;
}
}
}