迭代使用foreach XmlNodeList循环到达的XmlNode

本文关键字:XmlNode 循环 XmlNodeList foreach 迭代 | 更新日期: 2023-09-27 18:15:14

这是我用来遍历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。以下是当IF语句为真时,这个特定节点的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是第3个节点,这意味着我需要获得每个<nad>中的ID,然后获得每个<r>的第3个值。

最后的结果将是:

132, 8
433, 30
665, 90

目前,我假设第3个<r>值是我感兴趣的。将来,我应该在 <ns>CounterSales</ns>中计算并读取相应的数字,但现在没有必要。

再次感谢。

迭代使用foreach XmlNodeList循环到达的XmlNode

您可以这样做。我们的想法是迭代所有<ns>节点,以确定值为"CounterSales"的节点的索引。然后,我们使用该索引来选择相关的<r>

我还更改了初始<ni>的选择方式。按照您的方式,值"CounterSales"出现在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);
    }
}

使用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;
        }
    }
}
​