此查询正在从xml文件构建商品符号。
文件结构是
<Commodities>
<Grains>
<Commodity title="Corn" value="0" name="corn">
<Specs>
//other elements
<SymbolRoot>
<Platform value="ZC" name="globex"/>
<Platform value="C " name="bloomberg"/>
</SymbolRoot>
</Specs>
<ContractMonths firstnoticedaterule="" lasttradedaterule="The business day prior to the 15th calendar day of the contract month">
<Month value="Mar">
<Year value="2018" firstnoticedate="02/28/18" lasttradedate="03/14/18" dateformat="mm/dd/yy"/>
<Year value="2019" firstnoticedate="02/28/19" lasttradedate="03/14/19" dateformat="mm/dd/yy"/>
<Year value="2020" firstnoticedate="02/28/20" lasttradedate="03/13/20" dateformat="mm/dd/yy"/>
</Month>
</ContractMonths>
</Commodity>
</Grains>
<Commodities>
目前,我可以根据需要获得合同月数,但我也需要传入平台的符号root。现在它被硬编码为&#34; C&#34;
private List<string> GetAllSymbolsForContractMonths(CommodityList commodity, string platform)
{
var symCode = string.Empty;
var yrLastDigit = DateTime.Now.Year % 10;
//get the contract month symbol codes
var query = _doc.Descendants("Commodity")
.Where(c => c.Attribute("name")?.Value == commodity.ToString().ToLower())
.Descendants("ContractMonths").Elements("Month")
.Select(v => "C " + SymbolHelpers.GetSymbolContractMonthLetter(v.Attribute("value")?.Value) + yrLastDigit + " Comdty")
.ToList();
return query;
}
我知道有一些方法可以对Platform元素的value属性进行选择,并将该值设置为symCode变量,但我似乎无法正确使用它。然后我可以用变量替换硬编码。
答案 0 :(得分:2)
将您的查询拆分为两个。 首先,找到商品元素。
从该元素中,找到平台符号。 然后,构建列表。
private List<string> GetTypeFromVariable(CommodityList commodity, string platform)
{
var yrLastDigit = DateTime.Now.Year % 10;
var commodityElement = _doc.Descendants("Commodity")
.Where(x => x.Attribute("name")?.Value.Equals(commodity.ToString(), StringComparison.InvariantCultureIgnoreCase) ?? false)
.Single();
var symbol = commodityElement.Descendants("Platform")
.Where(x => x.Attribute("name")?.Value.Equals(platform, StringComparison.InvariantCultureIgnoreCase) ?? false)
.Single()
.Attribute("value").Value;
return commodityElement
.Descendants("ContractMonths").Elements("Month")
.Select(v => symbol + " " + SymbolHelpers.GetSymbolContractMonthLetter(v.Attribute("value")?.Value) + yrLastDigit + " Comdty")
.ToList();
}
答案 1 :(得分:1)
只是为了踢,有一些很酷的网站可以将您的XML转换为C#类(例如Xml2CSharp.com)。使用该工具,您可以创建一组类来反序列化,然后利用LINQ to Objects。
Commodities commodities = null;
using (var stream = new StringReader(xmlString))
{
XmlSerializer serializer = new XmlSerializer(typeof(Commodities));
commodities = (Commodities) serializer.Deserialize(stream);
}
var commodityName = "corn";
var platformName = "bloomberg";
var year = "2018";
var commodity = commodities.Grains.Commodity.Single(c => c.Name.Equals(commodityName, StringComparison.InvariantCultureIgnoreCase));
var symbol = commodity.Specs.SymbolRoot.Platform.Single(p => p.Name.Equals(platformName, StringComparison.InvariantCultureIgnoreCase));
var months = commodity.ContractMonths.Month.Year.Where(y => y.Value.Equals(year, StringComparison.InvariantCultureIgnoreCase));
以下是我使用该工具生成的类。这显然是更多的代码,但我喜欢有具体的类来使用。希望它有用。
[XmlRoot(ElementName = "Platform")]
public class Platform
{
[XmlAttribute(AttributeName = "value")]
public string Value { get; set; }
[XmlAttribute(AttributeName = "name")]
public string Name { get; set; }
}
[XmlRoot(ElementName = "SymbolRoot")]
public class SymbolRoot
{
[XmlElement(ElementName = "Platform")]
public List<Platform> Platform { get; set; }
}
[XmlRoot(ElementName = "Specs")]
public class Specs
{
[XmlElement(ElementName = "SymbolRoot")]
public SymbolRoot SymbolRoot { get; set; }
}
[XmlRoot(ElementName = "Year")]
public class Year
{
[XmlAttribute(AttributeName = "value")]
public string Value { get; set; }
[XmlAttribute(AttributeName = "firstnoticedate")]
public string Firstnoticedate { get; set; }
[XmlAttribute(AttributeName = "lasttradedate")]
public string Lasttradedate { get; set; }
[XmlAttribute(AttributeName = "dateformat")]
public string Dateformat { get; set; }
}
[XmlRoot(ElementName = "Month")]
public class Month
{
[XmlElement(ElementName = "Year")]
public List<Year> Year { get; set; }
[XmlAttribute(AttributeName = "value")]
public string Value { get; set; }
}
[XmlRoot(ElementName = "ContractMonths")]
public class ContractMonths
{
[XmlElement(ElementName = "Month")]
public Month Month { get; set; }
[XmlAttribute(AttributeName = "firstnoticedaterule")]
public string Firstnoticedaterule { get; set; }
[XmlAttribute(AttributeName = "lasttradedaterule")]
public string Lasttradedaterule { get; set; }
}
[XmlRoot(ElementName = "Commodity")]
public class Commodity
{
[XmlElement(ElementName = "Specs")]
public Specs Specs { get; set; }
[XmlElement(ElementName = "ContractMonths")]
public ContractMonths ContractMonths { get; set; }
[XmlAttribute(AttributeName = "title")]
public string Title { get; set; }
[XmlAttribute(AttributeName = "value")]
public string Value { get; set; }
[XmlAttribute(AttributeName = "name")]
public string Name { get; set; }
}
[XmlRoot(ElementName = "Grains")]
public class Grains
{
[XmlElement(ElementName = "Commodity")]
public List<Commodity> Commodity { get; set; }
}
[XmlRoot(ElementName = "Commodities")]
public class Commodities
{
[XmlElement(ElementName = "Grains")]
public Grains Grains { get; set; }
}