0

I have a complex XML file where I want to retrieve different values from the different Set tag.At the end, i need to take the values to a CSV file.

Please see the xml file format

I am trying to retrieve the value of

<szItemID>3268750004533</szItemID> from the first set 
<lMerchandiseStructureID>40</lMerchandiseStructureID> from the second set 
 <szDesc>PHG VIANDE SECHEE DE</szDesc>  from the third set 
 <dPackingUnitPriceAmount>75</dPackingUnitPriceAmount> from the fourth tag

I have tried to retrieve the first element through the below code but getting an error

NullReferenceException was unhandled Object reference not set to an instance of an object

Code

 XmlDocument document = new XmlDocument();
        document.Load(@"D:\\xml_1.xml");

        string myXmlString = document.OuterXml.ToString();

        XElement xml = XElement.Parse(myXmlString);

        Console.WriteLine(string.Format("{0}",xml.XPathSelectElement("/UpdateDB/Transaction/Insert/Set/szItemID").Value));

Please help

  StringBuilder dataToBeWritten = new StringBuilder();


        var doc = XDocument.Load(@"D:\xml_2.xml");

        foreach (var trans in doc.Descendants("Transaction"))

        {
            var val3 = (string)doc.Descendants("Set").Elements("szItemID").First();
            var val4 = (string)doc.Descendants("Set").Elements("lMerchandiseStructureID").First();
            var val5 = (string)doc.Descendants("Set").Elements("szName").First();
            var val6 = (string)doc.Descendants("Set").Elements("lRetailStoreID").First();
            var val7 = (string)doc.Descendants("Set").Elements("bIsContract").First();

            dataToBeWritten.Append(val3);
            dataToBeWritten.Append(",");
            dataToBeWritten.Append(val4);
            dataToBeWritten.Append(",");
            dataToBeWritten.Append(val5);
            dataToBeWritten.Append(",");
            dataToBeWritten.Append(val6);
            dataToBeWritten.Append(",");
            dataToBeWritten.Append(val7);
            dataToBeWritten.Append(",");
            dataToBeWritten.Append(Environment.NewLine);

        }


        Console.WriteLine(dataToBeWritten.ToString());

        Console.ReadLine();


        var testpath = @"D:\\Lutchmee2.csv";

        File.WriteAllText(testpath, dataToBeWritten.ToString());
Lutch
  • 119
  • 1
  • 14
  • Possible duplicate of [What is a NullReferenceException, and how do I fix it?](https://stackoverflow.com/questions/4660142/what-is-a-nullreferenceexception-and-how-do-i-fix-it) – Fabiano Jun 29 '17 at 08:41

1 Answers1

0

Your XElement is UpdateDB, so from that context there is no child UpdateDB. You'd have to amend your query to:

/Transaction/Insert/Set/szItemID

That said, it's unclear why you're loading the document into the DOM, converting it to a string and than parsing to an XElement. Just load into an XDocument and use your original query:

var doc = XDocument.Load(@"D:\xml_1.xml");
var val = (string) doc.XPathSelectElement("/UpdateDB/Transaction/Insert/Set/szItemID");

Or better still, use LINQ to XML as it was intended:

var val = (string) doc.Descendants("Set").Elements("szItemID").First()
Charles Mager
  • 25,735
  • 2
  • 35
  • 45
  • Many thanks for your reply..This works but i have another issue.. actually if i have an xml file with different transaction tags how do i retrieve each element from each transaction tag ?? Normally the example provided consist of information of one product, i may have file where i have two products..this i have different set of transaction tag.. Note the number of nodes within each transaction will stays the same – Lutch Jun 29 '17 at 09:48
  • @LBoodia `foreach (var trans in doc.Descendants("Transaction")) { .. }`? – Charles Mager Jun 29 '17 at 09:54
  • i have tried the above new code, but all my record are same even though i have different transaction tag with different values..any idea? Thanks so much – Lutch Jun 29 '17 at 10:24
  • @LBoodia you're not using the `trans` in your loop, you're using `doc`, so you will always get the same result. Use `trans.Descendants(...)` instead. – Charles Mager Jun 29 '17 at 10:26
  • what if i need to obtain the second value of the same element tag through the same transaction – Lutch Jun 29 '17 at 11:55
  • @LBoodia then instead of `First()` you'd call something like `Skip(1).First()`. – Charles Mager Jun 29 '17 at 12:07
  • How can i skip the next transaction tag? – Lutch Jul 07 '17 at 11:45
  • If the transaction set does not contain one mentioned element, i get an error that sequence contains no element. Is there a way i can validate if the element tag are present or not ? if it is not present to escape the transaction set and proceed with other transaction set? – Lutch Nov 08 '17 at 09:35
  • @Lutch if you use `FirstOrDefault` (instead of `First`), the expression will return `null` in the case there is no element rather than throwing an exception. – Charles Mager Nov 08 '17 at 14:23
  • how can i skip the transaction set incase the element is not present ? If my file contains 50 well structured transaction set and in one transaction set an element is missing i get an error and the whole file is not process. I cannot use null because if the whole row in the csv file has null values the file is not process – Lutch Nov 23 '17 at 09:34