0

With the following code, I'm currently reading <ns>CounterSales</ns> (the 3rd element) of every <nv>, which is great. I'm including the code and the XML.

Here's the code, works great if ElementAt is hardcoded :

var xDoc = XDocument.Parse(xmlStr);
var nvs = xDoc.Descendants("nv");
var nads = nvs.Select(nv => nv.Elements("nad").First().Value).ToList();
var thirdRs = nvs.Select(nv => nv.Elements("r").ElementAt(2).Value).ToList();

Here's the value of xmlStr:

<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>

But let's say that I would like to read more than one counter. I have a datatable that currently has two rows: [CounterSales] & [CounterBlah5]. I would like to process the other two counters the same way:

int index = 0;
DataTable results = GetCounters();
//results has two rows: [CounterSales] & [CounterBlah5]

foreach (DataRow row in results.Rows)
{
    string counter = cellRow["counter"]; //counter equals "CounterSales"
    /* Iterate through all <ns> to see where "CounterSales" is located.
       In this case, index = 2. On next foreach, index equals 4  */

    var xDoc = XDocument.Parse(xmlStr);
    var nvs = xDoc.Descendants("nv");
    var nads = nvs.Select(nv => nv.Elements("nad").First().Value).ToList();
    var thirdRs = nvs.Select(nv => nv.Elements("r").ElementAt(index).Value).ToList();
}

Any help is appreciated.

Thanks.

fdkgfosfskjdlsjdlkfsf
  • 3,165
  • 2
  • 43
  • 110

1 Answers1

0

If I understood your problem correctly, this is what you need

DataTable results = GetCounters();
//results has two rows: [CounterSales] & [CounterBlah5]

foreach (DataRow row in results.Rows)
{
    string counter = cellRow["counter"]; //counter equals "CounterSales"
    /* Iterate through all <ns> to see where "CounterSales" is located.
        In this case, index = 2. On next foreach, index equals 4  */                

    var xDoc = XDocument.Parse(xmlStr);

    //here we find the index
    var requiredIndex = xDoc.Descendants("ns")
            .Select((node, idx) => new { node, idx})
            .First(x => x.node.Value.Equals(counter)).idx;

    var nvs = xDoc.Descendants("nv");
    var nads = nvs.Select(nv => nv.Elements("nad").First().Value).ToList();
    var thirdRs = nvs.Select(nv => nv.Elements("r").ElementAt(requiredIndex).Value).ToList();
}

Edit: A shorter syntax to find index for List<T> from this post.

var requiredIndex = xDoc.Descendants("ns").ToList().FindIndex(x => x.Value == counter);
Community
  • 1
  • 1
Arghya C
  • 9,805
  • 2
  • 47
  • 66