My attempt to parse XML using Linq to XML failed. Despite the fact that as you see ItemList[0] below, I can get the ItemList
has many XML element items of the list ItemList (variable)
, the result shows only one XML element of the ItemList [0]
in ItemList (variable)
. I need to print out all elements on the ItemList [n]
.
Main Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
namespace WPF_ParsingXML.ViewModels.Helper
{
public class XMLHelper
{
public void ParseXML_Sample1()
{
// Read a file
XElement root = XElement.Load(Environment.CurrentDirectory @"\..\..\Sample.xml");
// Assign the default namespace
XNamespace aw = "http://www.adventure-works.com";
// Get values from elements
IEnumerable<XElement> ItemList =
from el in root.Elements(aw "PurchaseOrder")
select el.Element(aw "Items");
// Print
foreach (XElement el in ItemList)
{
Console.WriteLine("###################################");
Console.WriteLine((string)el.Element(aw "Item").Element(aw "ProductName"));
Console.WriteLine((string)el.Element(aw "Item").Attribute(aw "PartNumber"));
Console.WriteLine("###################################");
}
}
}
}
Sample.xml
<?xml version="1.0" encoding="utf-8"?>
<aw:PurchaseOrders xmlns:aw="http://www.adventure-works.com">
<aw:PurchaseOrder aw:PurchaseOrderNumber="99503" aw:OrderDate="1999-10-20">
<aw:Address aw:Type="Shipping">
<aw:Name>Ellen Adams</aw:Name>
<aw:Street>123 Maple Street</aw:Street>
<aw:City>Mill Valley</aw:City>
<aw:State>CA</aw:State>
<aw:Zip>10999</aw:Zip>
<aw:Country>USA</aw:Country>
</aw:Address>
<aw:Address aw:Type="Billing">
<aw:Name>Tai Yee</aw:Name>
<aw:Street>8 Oak Avenue</aw:Street>
<aw:City>Old Town</aw:City>
<aw:State>PA</aw:State>
<aw:Zip>95819</aw:Zip>
<aw:Country>USA</aw:Country>
</aw:Address>
<aw:DeliveryNotes>Please leave packages in shed by driveway.</aw:DeliveryNotes>
<aw:Items>
<aw:Item aw:PartNumber="872-AA">
<aw:ProductName>Lawnmower</aw:ProductName>
<aw:Quantity>1</aw:Quantity>
<aw:USPrice>148.95</aw:USPrice>
<aw:Comment>Confirm this is electric</aw:Comment>
</aw:Item>
<aw:Item aw:PartNumber="926-AA">
<aw:ProductName>Baby Monitor</aw:ProductName>
<aw:Quantity>2</aw:Quantity>
<aw:USPrice>39.98</aw:USPrice>
<aw:ShipDate>1999-05-21</aw:ShipDate>
</aw:Item>
</aw:Items>
</aw:PurchaseOrder>
<aw:PurchaseOrder aw:PurchaseOrderNumber="99505" aw:OrderDate="1999-10-22">
<aw:Address aw:Type="Shipping">
<aw:Name>Cristian Osorio</aw:Name>
<aw:Street>456 Main Street</aw:Street>
<aw:City>Buffalo</aw:City>
<aw:State>NY</aw:State>
<aw:Zip>98112</aw:Zip>
<aw:Country>USA</aw:Country>
</aw:Address>
<aw:Address aw:Type="Billing">
<aw:Name>Cristian Osorio</aw:Name>
<aw:Street>456 Main Street</aw:Street>
<aw:City>Buffalo</aw:City>
<aw:State>NY</aw:State>
<aw:Zip>98112</aw:Zip>
<aw:Country>USA</aw:Country>
</aw:Address>
<aw:DeliveryNotes>Please notify me before shipping.</aw:DeliveryNotes>
<aw:Items>
<aw:Item aw:PartNumber="456-NM">
<aw:ProductName>Power Supply</aw:ProductName>
<aw:Quantity>1</aw:Quantity>
<aw:USPrice>45.99</aw:USPrice>
</aw:Item>
</aw:Items>
</aw:PurchaseOrder>
<aw:PurchaseOrder aw:PurchaseOrderNumber="99504" aw:OrderDate="1999-10-22">
<aw:Address aw:Type="Shipping">
<aw:Name>Jessica Arnold</aw:Name>
<aw:Street>4055 Madison Ave</aw:Street>
<aw:City>Seattle</aw:City>
<aw:State>WA</aw:State>
<aw:Zip>98112</aw:Zip>
<aw:Country>USA</aw:Country>
</aw:Address>
<aw:Address aw:Type="Billing">
<aw:Name>Jessica Arnold</aw:Name>
<aw:Street>4055 Madison Ave</aw:Street>
<aw:City>Buffalo</aw:City>
<aw:State>NY</aw:State>
<aw:Zip>98112</aw:Zip>
<aw:Country>USA</aw:Country>
</aw:Address>
<aw:Items>
<aw:Item aw:PartNumber="898-AZ">
<aw:ProductName>Computer Keyboard</aw:ProductName>
<aw:Quantity>1</aw:Quantity>
<aw:USPrice>29.99</aw:USPrice>
</aw:Item>
<aw:Item aw:PartNumber="898-AM">
<aw:ProductName>Wireless Mouse</aw:ProductName>
<aw:Quantity>1</aw:Quantity>
<aw:USPrice>14.99</aw:USPrice>
</aw:Item>
</aw:Items>
</aw:PurchaseOrder>
</aw:PurchaseOrders>
ItemList[0]
<aw:Items xmlns:aw="http://www.adventure-works.com">
<aw:Item aw:PartNumber="872-AA">
<aw:ProductName>Lawnmower</aw:ProductName>
<aw:Quantity>1</aw:Quantity>
<aw:USPrice>148.95</aw:USPrice>
<aw:Comment>Confirm this is electric</aw:Comment>
</aw:Item>
<aw:Item aw:PartNumber="926-AA">
<aw:ProductName>Baby Monitor</aw:ProductName>
<aw:Quantity>2</aw:Quantity>
<aw:USPrice>39.98</aw:USPrice>
<aw:ShipDate>1999-05-21</aw:ShipDate>
</aw:Item>
</aw:Items>
Result
###################################
Lawnmower
872-AA
###################################
###################################
Power Supply
456-NM
###################################
###################################
Computer Keyboard
898-AZ
###################################
Expected Result
###################################
Lawnmower
872-AA
###################################
###################################
Baby Monitor
926-AA
###################################
Power Supply
456-NM
###################################
###################################
Computer Keyboard
898-AZ
###################################
###################################
Wireless Mouse
898-AM
###################################
CodePudding user response:
A better and simpler way.
c#
void Main()
{
const string filename = @"e:\Temp\Sample.xml";
XDocument xdoc = XDocument.Load(filename);
XNamespace aw = "http://www.adventure-works.com";
foreach (XElement el in xdoc.Descendants(aw "Item"))
{
Console.WriteLine("###################################");
Console.WriteLine(el.Element(aw "ProductName").Value);
Console.WriteLine(el.Attribute(aw "PartNumber").Value);
Console.WriteLine("###################################");
}
}
CodePudding user response:
If you read the documentation for Element, it says:
Gets the first (in document order) child element with the specified XName.
Please notice how it says "first child". In your case you want to retrieve all children, so you need to call Elements.
To do that, add a for each loop inside your current one.
foreach (XElement el in ItemList)
{
foreach (XElement elem in el.Elements(aw "Item")
{
// Rest of code left as exercise for reader
}
}
Sorry for any typos I'm typing on my phone.
As a side note, look into calling Descendants
if your only objective is getting the Items nodes.