我有一个由XML行组成的字符串,如下所示:
<FIXML>
<TrdCaptRpt TrdTyp = "0" TrdSubTyp = "7" />
</FIXML>
<FIXML>
<TrdCaptRptAck TrdTyp = "0" TrdSubTyp = "7" />
</FIXML>
<FIXML>
<TrdCaptRptAck TrdTyp = "1" />
</FIXML>
我有一些专门的LINQ查询:
var q =
from el in clearingMessagesDoc.Elements("ClearingMessages")
.Elements("FIXML")
.Elements("TrdCaptRpt")
.Where(f => f.Attribute("TrdTyp") != null)
select el.Attribute("TrdTyp");
var t =
from el in q
let trdtyp = el.Value
group trdtyp by trdtyp.Trim() into g
orderby g.Key descending
select new {
TrdType = g.Key,
Count = g.Count()
};
t.Dump("TrdCaptRpt");
q = from el in learingMessagesDoc.Elements("ClearingMessages")
.Elements("FIXML")
.Elements("TrdCaptRpt")
.Where(f => f.Attribute("TrdSubTyp") != null)
select el.Attribute("TrdSubTyp");
var t1 =
from el in q
let trdSubtyp = el.Value
group trdSubtyp by trdSubtyp.Trim() into g
orderby g.Key descending
select new {
TrdSubTyp = g.Key,
Count = g.Count()
};
虽然有效,但它会将报告类型(TrdCaptRpt
,TrdCaptRptAck
等)硬编码到查询中。如何修改查询,以便无论将来可能添加哪种报告类型,我都可以运行一个通用查询,告诉我每个TrdTyp
和TradSubType
的计数是否与TrdCaptRpt
,TrdCaptRptAck
等等?
所以问题是如何报告嵌套属性,如果它们存在,则按报告类型索引。
我希望得到这样的XML示例:
TrdCaptRpt
TrdTyp = "0" : 1
TrdSubTyp = "7" : 1
TrdCaptRptAck
TrdTyp = "0" : 1
TrdTyp = "1" : 1
TrdSubTyp = "7" : 1
如果还有其他任何属性,它也会给出关于这些属性的报告。
-
Response to Jeff:非常感谢,非常接近。我意识到我没有提供足够的信息。 XML文件相当复杂(为了简洁起见,这只是它的一小部分)。
<FIXML>
<TrdCaptRpt TrdTyp = "0" TrdSubTyp = "7">
<Hdr Snt="2011-05-18T12:26:09-05:00" />
<RptSide Side="2">
<Pty ID="GS" R="21"></Pty>
</RptSide >
</TrdCaptRpt>
</FIXML>
换句话说,每个级别可能有很多嵌套的东西。根据报告类型索引的示例,是否有通用的方法来计算每个属性的发生频率?
当我在一个看起来像这样的XML上运行你的查询时,它不会低于TrdCaptRpt。
感谢。
答案 0 :(得分:0)
因此,如果我在你的问题中理解了你的想法,我相信这就是你想要的:
var counts = clearingMessagesDoc
.Elements("ClearingMessages")
.Elements("FIXML")
.Elements()
.GroupBy(e => e.Name.ToString())
.ToDictionary(
g => g.Key,
g => g.SelectMany(e => e.Attributes())
.GroupBy(attr => new { Name = attr.Name.ToString(), Value = attr.Value.Trim() })
.OrderBy(attrg => attrg.Key.Name)
.ThenBy(attrg => attrg.Key.Value)
.ToDictionary(
attrg => String.Format("{0}=\"{1}\"", attrg.Key.Name, attrg.Key.Value),
attrg => attrg.Count()));
产生结果:
Element: TrdCaptRpt TrdSubTyp="7": 1 TrdTyp="0": 1
这将创建每个元素类型的属性/值对计数的字典字典。但是,它计算所有元素的所有属性。我无法分辨你想要计算的元素或属性。
如果您想进一步了解元素层次结构,请将上一次Elements()
调用更改为Descendants()
,这将包括所有嵌套元素及其属性计数。
var counts = clearingMessagesDoc
.Elements("ClearingMessages")
.Elements("FIXML")
.Descendants() // checks ALL elements in the hierarchy
.GroupBy(e => e.Name.ToString())
.ToDictionary(
g => g.Key,
g => g.SelectMany(e => e.Attributes())
.GroupBy(attr => new { Name = attr.Name.ToString(), Value = attr.Value.Trim() })
.OrderBy(attrg => attrg.Key.Name)
.ThenBy(attrg => attrg.Key.Value)
.ToDictionary(
attrg => String.Format("{0}=\"{1}\"", attrg.Key.Name, attrg.Key.Value),
attrg => attrg.Count()));
它产生以下结果:
Element: TrdCaptRpt TrdSubTyp="7": 1 TrdTyp="0": 1 Element: Hdr Snt="2011-05-18T12:26:09-05:00": 1 Element: RptSide Side="2": 1 Element: Pty ID="GS": 1 R="21": 1