简体   繁体   中英

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>

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" }
    ]
  }
]

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...
}

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();

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.

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