【问题标题】:Parsing XML Data with LINQ使用 LINQ 解析 XML 数据
【发布时间】:2010-11-25 08:46:36
【问题描述】:

我是 LINQ 新手,迫切需要快速完成这个项目。我需要为每个 MPrice 返回带有正确价格信息的 ID。任何建议都非常感谢!这是 XML 的一个示例:

<Pricing>
<MPrice>
    <Id>0079</Id>
      <Price>
        <Price>31.25</Price>
        <StartDt>2009-8-01</StartDt>
        <EndDt>2009-08-26</EndDt>
      </Price>
      <Price>
        <ListPrice>131.25</ListPrice>
        <StartDt>2009-08-26</StartDt>
        <EndDt>9999-12-31</EndDt>
       </Price>
   </MPrice>
   <MPrice>
    <Id>0081</Id>
      <Price>
        <Price>131.25</Price>
        <StartDt>2009-8-01</StartDt>
        <EndDt>2009-08-26</EndDt>
      </Price>
      <Price>
        <ListPrice>231.25</ListPrice>
        <StartDt>2009-08-26</StartDt>
        <EndDt>9999-12-31</EndDt>
       </Price>
   </MPrice> 
</Pricing>

【问题讨论】:

    标签: c# xml linq parsing


    【解决方案1】:

    这是一种方法:

    using System;
    using System.Linq;
    using System.Xml.Linq;
    
    class Program
    {
        static void Main()
        {
            String xml = @"<Pricing>
                <MPrice>
                    <Id>0079</Id>
                    <Price>
                    <Price>31.25</Price>
                    <StartDt>2009-8-01</StartDt>
                    <EndDt>2009-08-26</EndDt>
                    </Price>
                    <Price>
                    <ListPrice>131.25</ListPrice>
                    <StartDt>2009-08-26</StartDt>
                    <EndDt>9999-12-31</EndDt>
                    </Price>
                </MPrice>
               </Pricing>";
    
            var priceInfo = from e in XElement.Parse(xml).Elements("MPrice").Elements("Price")
                    let start = DateTime.Parse(e.Descendants("StartDt").FirstOrDefault().Value)
                    let end = DateTime.Parse(e.Descendants("EndDt").FirstOrDefault().Value)
                    where start < DateTime.Now && end > DateTime.Now
                    select new { Id = e.Parent.Element("Id").Value, ListPrice = e.Element("ListPrice").Value };
    
            Console.WriteLine(priceInfo.FirstOrDefault().Id);
            Console.WriteLine(priceInfo.FirstOrDefault().ListPrice);
        }
    }
    

    输出:

    0079
    131.25
    

    请注意,需要进行比此示例提供的更多的错误检查。我会特别添加对日期时间解析的检查(可能通过使用包装DateTime.TryParseExact 的函数)。

    编辑:如果您想使用XDocument 而不是XElement,您需要对查询进行细微的更改(注意使用Descendants 方法而不是Elements 方法):

    var priceInfo = from e in XDocument.Parse(xml).Descendants("MPrice").Elements("Price")
            let start = DateTime.Parse(e.Descendants("StartDt").FirstOrDefault().Value)
            let end = DateTime.Parse(e.Descendants("EndDt").FirstOrDefault().Value)
            where start < DateTime.Now && end > DateTime.Now
            select new { Id = e.Parent.Element("Id").Value, ListPrice = e.Element("ListPrice").Value };
    

    请记住,您不需要使用XDocument,除非您将 XML 作为真正的文档使用。在大多数情况下,XElement 类型就足够了。

    编辑#2:如果您想从磁盘加载XDocument,请使用以下方法:

    using System;
    using System.Linq;
    using System.Xml.Linq;
    
    class Program
    {
        static void Main()
        {
            XDocument document = XDocument.Load(@"d:\test.xml");
    
            var priceInfo = from e in document.Descendants("MPrice").Elements("Price")
                    let start = DateTime.Parse(e.Descendants("StartDt").FirstOrDefault().Value)
                    let end = DateTime.Parse(e.Descendants("EndDt").FirstOrDefault().Value)
                    where start < DateTime.Now && end > DateTime.Now
                    select new { Id = e.Parent.Element("Id").Value, ListPrice = e.Element("ListPrice").Value };
    
            Console.WriteLine(priceInfo.FirstOrDefault().Id);
            Console.WriteLine(priceInfo.FirstOrDefault().ListPrice);
        }
    }
    

    【讨论】:

    • 我可以用 XDocument 代替 XElement 做同样的解析吗?
    • 似乎仍然不起作用。我正在使用:XDocument xmlDoc = XDocument.Load("my.xml");现在,当我调用: XDocument.Parse(xml).Descendants("MPrice").Elements("Price") 我收到未将 XDocument 转换为字符串的错误。有什么想法吗?
    • 如果您已经将 XML 加载到 XDocument 中,则无需调用 XDocument.Parse。我将再次编辑以演示如何处理磁盘上的 XML 文件。
    • 感谢您的时间和帮助。这个项目几乎完成了,我学到了一些新东西。谢谢
    【解决方案2】:
    string id = yourDocument
                    .Descendants("Pricing")
                    .Descendants<XElement>("MPrice")
                    .Where<XElement>(i => i.Descendants("Price")
                                            .Descendants<XElement>("StartDt")
                                            .Select<XElement, DateTime>(s => DateTime.Parse(s.Value))
                                            .FirstOrDefault<DateTime>().Date == DateTime.Now.Date)
                    .Select<XElement, string>(i => i.Descendants("Id").FirstOrDefault<XElement>().Value)
                    .FirstOrDefault<string>();
    

    假设 id 是一个字符串,这应该可以工作。您可以将其设为 int。

    你应该做一些检查以确保日期是正确的等等...... . ,但这是一个快速示例,如果开始日期更改为 2009-9-03 或当前日期日期,则它应该适用于给定的 Xml 示例。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-06-13
      • 1970-01-01
      • 2012-01-20
      • 1970-01-01
      • 1970-01-01
      • 2012-05-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多