LavsTo
LavsTo

Reputation: 129

Select Next Sibling if Element in previous sibling is a certain value XML

I have the following XML file

<ProdExtract>
<Product>
  <Barcode>         
    <Eancode>0000000000000</Eancode>        
  </Barcode>                    
  <Barcode>         
    <Eancode>0000000000000</Eancode>        
  </Barcode>                          
  <Barcode>         
    <Eancode>5391524344444</Eancode>        
  </Barcode>
</Product>

<Product>                                                  
  <Barcode>         
    <Eancode>5391524322222</Eancode>        
  </Barcode>
</Product>
</ProdExtract>

The desired ouput is to get the Eancode of both products. For the first product, to skip all the zero barcode and select/ouput the next valid Eancode (5391524344444) for that product. For the second product output that valid default Eancode (5391524322222).

By default this is how I am extracting the Eancode for a product that only has one Barcode node

p.q_barcode = node.SelectSingleNode("Barcode/Eancode").FirstChild.InnerText;

Issue is dealing with the product that has multiple invalid zero value Eancodes before extracting the next valid one.

With current code

XmlDocument xDoc = new XmlDocument();
xDoc.Load(data);
XmlElement root = xDoc.DocumentElement;
XmlNodeList nodes = root.SelectNodes("Product");

foreach (XmlNode node in nodes)                        
{

   var noneZeroEancode = xml.Descendants("Eancode").Where(x => x.Value != "0000000000000");
   string outputString = eancode.First().Value;
   p.q_barcode = outputString;
   //other properties....
   p.q_description = node.SelectSingleNode("ProductID/LongDescription").InnerText;
   //insert record into table
   //go read next "Product" node (if any)
}

Output result: on reading the second node, it is assigning value of first Eancode to the second product. So all products that follow have the Eancode value of 5391524344444 instead of their own unique value.

Additional Info (Just for clarity): This functionality is within a loop that reads each product node, maps the values to table columns and imports the record/product, then moves on to read the next node. This part needs no answer as I have that solved.

Upvotes: 0

Views: 898

Answers (1)

Dweeberly
Dweeberly

Reputation: 4777

Try something like this:

using System;
using System.Linq;
using System.Xml.Linq;

namespace xml {
    class Program {
        static void Main(string[] args) {
            var data =
@"<ProdExtract>
    <Product>
        <Barcode>         
          <Eancode>0000000000000</Eancode>        
        </Barcode>
    </Product>
    <Product>
        <Barcode>         
          <Eancode>0000000000000</Eancode>        
        </Barcode>
    </Product>
    <Product>       
        <Barcode>         
          <Eancode>5391524344444</Eancode>        
        </Barcode>
    </Product>
</ProdExtract>";

            var xml = XDocument.Parse(data);
            var eancode = xml.Descendants("Eancode").Where(x => x.Value != "0000000000000");
            var product = eancode.Select(x => x.Parent.Parent);
            foreach (var p in product) {
                Console.WriteLine(p);
                }
            }
        }
    }

The first step is to select elements that don't have the 00...0 Eancode value. Next look at each of the returned nodes (XElements) and get the grandparent.

Possible issue: If your XML isn't formatted as expected (if 'Eancode' exists but isn't within a 'Product/Barcode') you would not get the expected results, you could even generate an exception getting the parent of the parent.

Upvotes: 1

Related Questions