簡體   English   中英

使用具有多個屬性值的xpath獲取xml doc子節點

[英]Getting xml doc subnodes using xpath with multiple attribute values

給定具有以下結構的xml

<Commodity name="coffee" title="Coffee" value="7">
  <Specs>
     ..elements removed
  </Specs>
  <ContractMonths lasttradedaterule="Eight business days prior to the last business day of the delivery month"
            firstnoticedaterule="Seven business days prior to first business day of delivery month">
     ..elements removed
  </ContractMonths>
 <Options tf="true">
   <OptionMonths delimeter="comma"
             expirationdaterule="Second Friday of the calendar month preceding such regular or serial
                option month; provided, however, that for each option, there will be a minimum of four
                trading days between the last trading day of the expiring option and the first notice
                day of the expiring future">
    <Year value="2015">
      ..elements removed
    </Year>
    <Year value="2016">
      ..elements removed
    </Year>
    <Year value="2017">
     ..elements removed
    </Year>
    <Year value="2018">
      <Jan expiration="" associatedcontract="Mar" />
      <Feb expiration="" associatedcontract="Mar" />
      <Mar expiration="02/12/18" associatedcontract="Mar" />
      <Apr expiration="" associatedcontract="May" />
      <May expiration="04/08/18" associatedcontract="May" />
      <Jun expiration="05/11/18" associatedcontract="Jul" />
      <Jul expiration="06/08/18" associatedcontract="Jul" />
      <Aug expiration="07/13/18" associatedcontract="Sep" />
      <Sep expiration="08/10/18" associatedcontract="Sep" />
      <Oct expiration="" associatedcontract="Dec" />
      <Nov expiration="" associatedcontract="Dec" />
      <Dec expiration="11/09/18" associatedcontract="Dec" />
    </Year>
  <Year value="2019">
   ..elements removed
  </Year>     
</OptionMonths>

超過25種商品元素

我可以使用name屬性值檢索想要的商品元素

 var doc = XDocument.Load(@"https://batlgroupimages.blob.core.windows.net/accessibleimages/CommodityData.xml");

        IEnumerable<XElement> elem =
            doc.Descendants("Commodity").Where(el =>
            {
                var xAttribute = el.Attribute("name");
                return xAttribute != null && xAttribute.Value == commodity;
            });

給定Year元素的value屬性等於我傳入的任何年份,我需要進一步挖掘以獲得year元素的節點列表。

我正在嘗試在一份聲明中做到這一點

var dates = elem.Descendants("Options/@tf='true'/OptionMonths/Year/@value='2015'");

它正確讀取(無論如何對我而言),獲取后備選項的tf值為true,獲取OptionMonths / Years,其中年值為= 2015

我可以用更短的步驟來做,但是我確定有一個更快的解決方案。

更新基於jdweng的答案,我想出了返回過去的一年中的方法如下

var year = elem.Descendants("Options")
            .Where(x => x.Attribute("tf")?.Value == "true").Descendants("Year")
            .Where(y => (string)y.Attribute("value") == yearvalue);

嘗試以下操作:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;

namespace ConsoleApplication1
{
    class Program
    {
        const string FILENAME = @"c:\temp\test.xml";
        static void Main(string[] args)
        {
            XDocument doc = XDocument.Load(FILENAME);
            string xAttribute = "coffee";
            Dictionary<int, Dictionary<string, KeyValuePair<string, string>>> dict = doc.Descendants("Commodity").Where(el => xAttribute == (string)el.Attribute("name"))
                .Select(x => x.Descendants("Year")
                .GroupBy(s => (int)s.Attribute("value"), t => t.Elements()
                    .GroupBy(u => u.Name.LocalName, v => new KeyValuePair<string, string>((string)v.Attribute("expiration"), (string)v.Attribute("associatedcontract")))
                        .ToDictionary(u => u.Key, v => v.FirstOrDefault()))
                        .ToDictionary(s => s.Key, t => t.FirstOrDefault())).FirstOrDefault();

        }
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM