[英]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.