简体   繁体   中英

Check if XML node exists - Loop not finding node if its available

I have an XML file were some records have certain nodes/elements missing (information needed for import into table). If a certain node is missing for that record then I set a default value and move on the next record. In the sample XML file, Product A has no Barcode node so generate that value based on other information, Product B has all the nodes required so all values are taken from the nodes.

<ProdExtract>
<Product>
    <BasicFields>
        <ProductCode>000011</ProductCode>
        <LongDescription>Product A</LongDescription>
    </BasicFields>
</Product>

<Product>
    <BasicFields>
        <ProductCode>000012</ProductCode>
        <LongDescription>Product B</LongDescription>
    </BasicFields>
    <Barcode>         
      <Eancode>5391524344444</Eancode>        
    </Barcode>
</Product>
</ProdExtract>

My C# code to is as follows.

foreach (XmlNode node in nodes)                        
{
   XmlNodeList barcodeExists = xDoc.GetElementsByTagName("Product/Barcode");

   if (barcodeExists.Count > 0)
   {
      /*get the inner text of that node*/
      p.q_barcode = node.SelectSingleNode("Barcode/Eancode").FirstChild.InnerText;
   }
   else
   {
      /* ---
      If product has no Barcode node,
      Lets set our default value for products without that node
      --- */        
   }
}

Now when the check goes through the first record that does not have the barcode node, it is going to the else statement and running the code needed to generate a value and inserting that first record perfectly. On the second check for the record with all nodes it is still somehow jumping over to the the else and generating a value when it should simple take the value from the if inner text of the "Barcode/Eancode". Even swapping around the records and putting Product B first is still giving the same issue.

I have even tried the following way, and its still not getting the appropriate value for Product B

var barcodeExists = node.SelectSingleNode("Product/Barcode");

if (barcodeExists != null)
{
   /*Barcode node exists, get the value from that node*/
   p.q_barcode = node.SelectSingleNode("Barcode/Eancode").FirstChild.InnerText;
}

To get the list of nodes, you need to pass just the node name to the method GetElementsByTagName

var node = xmlDoc.GetElementsByTagName("Barcode");

Attached is the screen shot showing it's value in Visual Studio debugger

在此处输入图片说明

Also, to add your Xml is not fully right.

I have changed it to make a proper Xml. The Sample I used is

<ProdExtract>
    <Product>
        <BasicFields>
            <ProductCode>000011</ProductCode>
            <LongDescription>Product A</LongDescription>
        </BasicFields>
    </Product>

    <Product>
        <BasicFields>
            <ProductCode>000012</ProductCode>
            <LongDescription>Product B</LongDescription>
        </BasicFields>
        <Barcode>         
            <Eancode>5391524344444</Eancode>        
        </Barcode>
    </Product>
</ProdExtract>

You can parse your Xml similar to this:

        var nodeList = xmlDoc.GetElementsByTagName("Barcode");

        if (nodeList != null)
        {
            if (nodeList.Count > 0)
            {
                var element = nodeList[0];

                string value = element.InnerText;
            }
        }

The full method to construct an object based on Xml

The logic in this method it to navigate the Xml and pick the required values and set it to the object.

    private static Product[] GetDetails(XmlDocument xmlDoc)
    {
        var result = new List<Product>();
        XmlNode tempNode;

        var nodeList = xmlDoc.GetElementsByTagName("Product");

        foreach(XmlNode node in nodeList)
        {
            var product = new Product();

            tempNode = node.FirstChild; //BasicFields

            if (tempNode != null)
            {
                product.ProductCode = tempNode["ProductCode"].InnerText;
                product.LongDescription = tempNode["LongDescription"].InnerText;
            }

            if (node.ChildNodes.Count > 1)
            {
                tempNode = node.ChildNodes[1];

                if (tempNode != null)
                {
                    tempNode = tempNode.FirstChild; //Eancode
                    if (tempNode != null)
                    {
                        product.Barcode = tempNode.InnerText;
                    }
                }
            }

            result.Add(product);
        }

        return result.ToArray();
    }

In the above example, Product is a simple Class to hold the data

class Product
{
    public string ProductCode { get; set; }
    public string LongDescription { get; set; }
    public string Barcode { get; set; }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM