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.