简体   繁体   English

从XML文件提取特定项目

[英]Extracting Specific Items from an XML File

All, 所有,

I have been writing some code to attempt to extract a collection of items from an XML file using C#. 我一直在编写一些代码,以尝试使用C#从XML文件中提取项目集合。 I have been reading around and have decided to go down the LINQ route using 我一直在阅读,并决定使用以下方法走LINQ路线

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层次结构的相对复杂性,我对如何访问relevent元素(在本例中为以下XML的'dCost'和'iCost')感到有些困惑:

<?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: 到目前为止,我仅阅读dCost的内容如下:

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. 我看了很多示例,但是XML总是嵌入得很少,因此很难扩展这些示例。 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: 编辑:我现在也意识到,由于我的XML文件太大,我将需要使用以下内容:

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? 您的x路径中有两次情节-应该不是// message / episodes / episode / episodeCosts?

Edit: Assuming your problem is that the x-path query return no results. 编辑:假设您的问题是x路径查询不返回任何结果。 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. 如果您删除了xmlns定义xmlns="urn://www.XXXX.com/vcopdc/2011/01/v0.5"我相信您的代码将可以正常工作。 If you want to use the Xml namespace use XPathSelectElements Method (XNode, String, IXmlNamespaceResolver). 如果要使用Xml命名空间,请使用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. 谢谢您的帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM