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

时间:2015-09-29 19:33:18

标签: 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("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>并阅读适当的数字,但现在不需要。

再次感谢。

2 个答案:

答案 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;

        }
    }
}
​