我应该使用什么linq来跟踪XDocument?

时间:2013-09-14 12:24:54

标签: linq-to-xml

我想根据我的XDocument中的“MASTERKEY”元素创建多个不同的List<string> s或var或任何其他集合,并希望根据RMSId过滤结果。

下面的XML示例如果我过滤RMSId =“xyz”,那么我应该有3个“MASTERKEY”元素集合(美国,英国,欧元),集合应该包含“BM”元素作为值

对于RMSId =“xyz” - 美国系列将包含{FX-SP,IR-D}

对于RMSId =“xyz” - 英国系列将包含{FX-S,FX-SUK}

我正在尝试使用LINQ to XML,但我仍在学习并发现难以运行。请指教。

如果您需要任何进一步的细节或寻求任何明确性,请告诉我。

<MSKEYS>
  <RM>
    <RMS Id="xyz">
      <Details>
        <MDetails>
          <BM>FX-SP</BM>
          <CM>123</CM>
          <RC>456</RC>
          <MASTERKEY>USA</MASTERKEY>
          <Filter>NYK</Filter>
        </MDetails>
        <MDetails>
          <BM>IR-D</BM>
          <CM>789</CM>
          <RC>456</RC>
          <MASTERKEY>USA</MASTERKEY>
          <Filter>CHIC</Filter>
        </MDetails>
        <MDetails>
          <BM>FX-SUK</BM>
          <CM>3453</CM>
          <RC>4353453</RC>
          <MASTERKEY>UK</MASTERKEY>
          <Filter>LOND</Filter>
        </MDetails>
        <MDetails>
          <BM>FX-V</BM>
          <CM>44</CM>
          <RC>O23F</RC>
          <MASTERKEY>EUR</MASTERKEY>
          <Filter>ITY</Filter>
        </MDetails>
        <MDetails>
          <BM>FX-S</BM>
          <CM>4676</CM>
          <RC>45646</RC>
          <MASTERKEY>UK</MASTERKEY>
          <Filter>ENG</Filter>
        </MDetails>
      </Details>
    </RMS>
    <RMS RunId="abcd">
      <Details>
        <MDetails>
          <BM>FX-SPS</BM>
          <CM>4676</CM>
          <RC>45646</RC>
          <MASTERKEY>USA</MASTERKEY>
          <Filter>NYK</Filter>
        </MDetails>
        <MDetails>
          <BM>PC</BM>
          <CM>4646</CM>
          <RC>7979</RC>
          <MASTERKEY>UK</MASTERKEY>
          <Filter>LOND</Filter>
        </MDetails>
      </Details>
    </RMS>
  </RM>
</MSKEYS>

1 个答案:

答案 0 :(得分:0)

我建议使用Dictionary<string, List<string>>,其中“MASTERKEY”的值是键,值是List<string>,包含该键的所有“BM”元素。然后,您可以通过密钥访问值列表。

这可能不是最优雅的方式,但它可以工作(在VS 2012中在Win7 64位上测试):

XDocument xDoc = XDocument.Load(xmlFile);
// Use XDocument.Parse(xmlString) if you have a string instead of a file

Dictionary<string, List<string> myResults = new Dictionary<string, List<string>>();
myResults = (from x in xDoc.Root.Elements("RM").Elements("RMS")
            where (string)x.Attribute("id") == "xyz"
            from d in x.Element("Details").Elements("MDetails")
            group d by (string)d.Element("MASTERKEY") ?? "Unknown" into g
            select new
            {
                MASTERKEY = g.Key,
                BM = g.Select(bm => (string)bm.Element("BM")).ToList()
            }).ToDictionary(k => k.MASTERKEY, v => v.BM);

基于您的XML示例,这将提供一个包含三个键(美国,英国和欧元)的字典,每个键都有该键的“BM”值的相应列表。

一些注意事项 - 我使用(string)代替.Value来处理元素缺失或属性丢失的情况 - 它将返回null。

在密钥的情况下,我更进一步使用空合并运算符(??)来设置默认值“Uknown”,以防未找到“MASTERKEY”元素以防止尝试将空键插入字典。