【问题标题】:Query for all nested XML types in LINQ在 LINQ 中查询所有嵌套的 XML 类型
【发布时间】:2011-06-27 20:10:31
【问题描述】:

我有一个由 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() 
    };

这可行,但它将报告类型(TrdCaptRptTrdCaptRptAck 等)硬编码到查询中。如何修改查询,以便将来无论添加哪种报告类型,我都可以运行一个通用查询,该查询将告诉我每个 TrdTypTradSubType 的计数对应于它是否为 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。

谢谢。

【问题讨论】:

  • 我已经删除了注释掉的代码,这太吵了。因此,如果我正确理解您的问题,您只想计算每个元素名称的 FIXML 元素下的元素中有多少属性?
  • p.s.,只是提示,如果您想引起提供答案的人的注意,请对答案发表评论。我没有收到有关您对帖子或任何其他答案所做的任何更新的任何通知。我通常会注意到您的更新,但我遇到了一些连接问题,所以我无法像往常那样频繁地检查 SO。我将通过更新我的答案来解决您的更新。

标签: c# linq linq-to-xml


【解决方案1】:

因此,如果我理解您在问题中想要什么,我相信这就是您想要的:

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()));

它产生结果:

元素:TrdCaptRpt TrdSubTyp="7": 1 TrdTyp="0": 1

这将创建一个字典,其中包含每个元素类型的属性/值对的计数。然而,它计算 all 元素的 all 属性。我不知道你想计算哪些元素或属性。


如果您想进一步深入元素层次结构,请将最后一个 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()));

它产生以下结果:

元素:TrdCaptRpt TrdSubTyp="7": 1 TrdTyp="0": 1 元素:HDR Snt="2011-05-18T12:26:09-05:00": 1 元素:RptSide 边=“2”:1 元素:Pty ID="GS": 1 R="21": 1

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多