簡體   English   中英

在LINQ中查詢所有嵌套的XML類型

[英]Query for all nested XML types in LINQ

我有一個包含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的計數,它們TradSubType對應於TrdCaptRptTrdCaptRptAck等。

因此,問題在於如何對嵌套屬性(如果存在)進行報告,並按報告類型建立索引。

我希望從給出的XML示例中獲得類似的信息:

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

TrdCaptRptAck 
    TrdTyp = "0" : 1
    TrdTyp = "1" : 1
    TrdSubTyp = "7" : 1

如果還有其他屬性,它也會為這些屬性提供報告。

-

回復傑夫 :謝謝,非常非常接近。 我意識到我沒有提供足夠的信息。 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。

謝謝。

因此,如果我了解您在問題中想要的內容,那么我相信這就是您想要的:

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

暫無
暫無

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

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