Pomster
Pomster

Reputation: 15207

Read values from XML nodes?

I am trying to pull information out of an XML String, but i am struggling looping through the nodes.

XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(OrderXml);
XmlNodeList parentNode = xmlDoc.GetElementsByTagName("SalesOrders");
XmlNodeList SalesOrderNode = xmlDoc.GetElementsByTagName("SalesOrder");
XmlNodeList parentNode2 = xmlDoc.GetElementsByTagName("WarningMessages");
foreach (XmlNode childrenNode in parentNode2)
{
  string test = childrenNode.Value.ToString();
}

I would like to Grab SalesOrder number, in this case its r31283, After which i would like to loop through the contents of WarningMessages. I need to grab the line number and stock code for each warning description.

My XML:

<?xml version="1.0" encoding="Windows-1252"?>
<SalesOrders Language='05' Language2='EN' CssStyle='' DecFormat='1' DateFormat='01' Role='01' Version='6.1.085' OperatorPrimaryRole='100'>
<TransmissionHeader>
<TransmissionReference>00000000000003</TransmissionReference>
<SenderCode/> 
<DatePrepared>2014-05-22</DatePrepared>
<TimePrepared>09:12</TimePrepared>
</TransmissionHeader>
<Order>
<CustomerPoNumber>RQ140522-33</CustomerPoNumber>
<SalesOrder>r31283</SalesOrder>
<OrderActionType>A</OrderActionType>
<BackOrderComment>One or more lines have been placed on back order for order 'r31283'</BackOrderComment>
<WarningMessages>
<WarningDescription>Line 0001 for stock code 'NN0410BP01' was placed on back order</WarningDescription>
<WarningDescription>Line 0002 for stock code 'NN0400GR08' was placed on back order</WarningDescription>
<WarningDescription>Line 0003 for stock code 'NN0410BN01' was placed on back order</WarningDescription>
<WarningDescription>Line 0004 for stock code 'NN0370BH01' was placed on back order</WarningDescription>
<WarningDescription>Line 0005 for stock code 'NN0370BH02' was placed on back order</WarningDescription>
<WarningDescription>Line 0006 for stock code 'NN0390BC01' was placed on back order</WarningDescription>
<WarningDescription>Line 0007 for stock code 'NN0410HL01' was placed on back order</WarningDescription>
<WarningDescription>Line 0008 for stock code 'NN0410FD07' was placed on back order</WarningDescription>
<WarningDescription>Line 0009 for stock code 'NN0410FD08' was placed on back order</WarningDescription>
<WarningDescription>Line 0010 for stock code 'NN0400VL02' was placed on back order</WarningDescription>
</WarningMessages>
</Order>
</SalesOrders>

Upvotes: 1

Views: 95

Answers (4)

Gal Ziv
Gal Ziv

Reputation: 7372

first use XDocument class so you can use LINQ to XML then query this docuemnt. use the the Descendants method to get all the elements in doc. then search for the ones with the SalesOrder tag name using the Name property. since you expect only one matched element use the First() method on the result to get the matched tag value.

    XDocument doc = XDocument.Load("some.xml");
    var result = from n in doc.Descendants() where n.Name == "SalesOrder" select n.Value;
    string val = result.First();

Upvotes: 0

Gleb
Gleb

Reputation: 1432

Try like this:

XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(OrderXml);
XmlNode parentNode = xmlDoc.SelectSingleNode("SalesOrders");
XmlNode SalesOrderNode = xmlDoc.SelectSingleNode("SalesOrder");
XmlNodeList lstWarning = xmlDoc.SelectNodes("WarningMessages/WarningDescription");
foreach (XmlNode childrenNode in lstWarning)
{ 
    string test = childrenNode.InnerText;
}

And also read something about XPath.

Upvotes: 0

Sergey Berezovskiy
Sergey Berezovskiy

Reputation: 236328

I recommend to use Linq to Xml:

var xdoc = XDocument.Load(path_to_xml);
Regex regex = new Regex(@"Line (?<line>\d+) for stock code '(?<code>\w+)'");
var orders = from o in xdoc.Root.Elements("Order")
             select new
             {
                 SalesOrder = (string)o.Element("SalesOrder"),
                 WarningMessages =
                     from m in o.Element("WarningMessages").Elements()
                     let match = regex.Match((string)m)
                     where match.Success
                     select new
                     {
                         Line = match.Groups["line"].Value,
                         Code = match.Groups["code"].Value
                     }
             };

Output:

[
  {
     SalesOrder: "r31283",
     WarningMessages: [
       { Line: "0001", Code: "NN0410BP01" },
       { Line: "0002", Code: "NN0400GR08" },
       { Line: "0003", Code: "NN0410BN01" },
       { Line: "0004", Code: "NN0370BH01" },
       { Line: "0005", Code: "NN0370BH02" },
       { Line: "0006", Code: "NN0390BC01" },
       { Line: "0007", Code: "NN0410HL01" },
       { Line: "0008", Code: "NN0410FD07" },
       { Line: "0009", Code: "NN0410FD08" },
       { Line: "0010", Code: "NN0400VL02" }
    ]
  }
]

Upvotes: 4

Pylyp Lebediev
Pylyp Lebediev

Reputation: 2131

You can do it by using LINQ to XML

// Load XML file.
var doc = XDocument.Load(path);

// Find SalesOrder element.
var salesOrder = (from c in doc.Descendants("SalesOrder")
                 select c.Value).FirstOrDefault();

// Find warning message elements.
var warningMessages = (from c in doc.Descendants("WarningDescription")
                      where c.Parent != null && c.Parent.Name == "WarningMessages"
                      select c.Value).ToList();

Then loop thought the warning messages

foreach(var warningMessage in warningMessages)
{
    // Handle warning message...
}

Upvotes: 1

Related Questions