All,
I have been writing some code to attempt to extract a collection of items from an XML file using C#. I have been reading around and have decided to go down the LINQ route using
using System.Xml.XPath;
using System.Xml.Linq;
However, due to the relative complexity of the XML hierarchy, I am getting a bit confused over how to access the relevent elements, which in this case are 'dCost' and 'iCost' from the following XML:
<?xml version="1.0" encoding="utf-8"?>
<message xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
pStart="2010-01-01T12:12:12"
pEnd="2010-01-01T12:12:12"
fYear="2010-11"
OrgID="21122211" xmlns="urn://www.XXXX.com/vcopdc/2011/01/v0.5">
<episodes>
<episode
eKey="001448101"
ur="1219765"
campus="1334"
eStart="17/01/2010 6:00:00 AM"
eEnd="17/01/2010 11:00:00 AM"
stream="X"
dob="6/12/1936 12:00:00 AM"
atsi="2"
pCode="3075">
<episodeCosts>
<episodeCost
area="A0902"
description="General ATOMIC"
account="GF"
dCost="0.0393072400937604"
iCost="0.156445858061913"
location="101"
sDate="17/01/2000 12:00:00 AM" />
<episodeCost
area="AAS2W"
description="General ATOMIC"
account="LAB"
dCost="0.0169883227585181"
iCost="0.0110702327817353"
location="101"
sDate="17/01/2000 12:00:00 AM" />
</episodeCosts>
</episode>
</episodes>
</message>
What I have got so far is the following to read the dCost only:
var doc = XDocument.Load(strFileName);
var values = doc.XPathSelectElements("//message/episodes/episode/episodeCosts");
foreach (var item in values)
{
foreach (var att in item.Elements("episodeCost"))
{
var value = att.Attribute("dCost").Value;
}
}
which does not work, that is, it is not finding the the element I want it to, as my syntax is not quite right. I have looked at many examples but the XML is always much less embedded, so it is difficult to extend the examples. Any help would be most appreciated.
EDIT: I have now also realised that due to the fact that my XML file are so large, I will need to use something like:
using (var reader = XmlReader.Create(strFileName))
{
while (reader.Read())
{
// Some code here.
}
}
Again any help is most appreciated.
Your x-path has episodes in it twice - should it not be //message/episodes/episode/episodeCosts?
Edit: Assuming your problem is that the x-path query return no results. If not, what does happen?
You could just do this as
var doc = XDocument.Load(strFileName);
var CostElements = doc.Elements("message").Elements("episodes").Elements("Episode").Elements("episodeCosts").Elements("EpisodeCost");
foreach(var cost in CostElements)
{
var iCost = cost.Attribute("icost").Value;
var dCost = cost.Attribute("dcost").Value;
}
Does that work for you?
I belive if you remove the xmlns definition xmlns="urn://www.XXXX.com/vcopdc/2011/01/v0.5"
your code will work. If you want to use the Xml namespace use XPathSelectElements Method (XNode, String, IXmlNamespaceResolver).
Details here
This is how I did this eventually. Perhaps it will help someone in the future.
double dTotalICostMM = 0.0, dTotalDCostMM = 0.0;
decimal dCost = Decimal.Zero, iCost = Decimal.Zero;
using (XmlReader reader = XmlReader.Create(strFileName))
{
while (reader.Read())
{
if (reader.NodeType == XmlNodeType.Element && reader.Name == "episodeCost")
{
dCost = Convert.ToDecimal(reader.GetAttribute("dCost"));
iCost = Convert.ToDecimal(reader.GetAttribute("iCost"));
}
}
// Add each cost to its total for the month
dTotalDCostMM += (double)dCost;
dTotalICostMM += (double)iCost;
}
Thanks for the help.
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.