【问题标题】:How to select multiple attributes如何选择多个属性
【发布时间】:2017-06-01 08:43:10
【问题描述】:

我有以下 xml 架构,我想在哪里使用 linq 来查询 2 个属性。我四处寻找,但没有找到合适的解决方案。

<Object class="MA" Name="Sample">
  <bist name="act">false</bist>
  <bist name="Dynamic">1234</bist>
  <bist name="Fast">false</bist>
  <bist name="plane">false</bist>
  <bist name="Tnl">2232</bist>
</Object>

对于上面的xml,在得到“Dynamic”的值并与oldTnl变量比较后,如果相等,我想选择或获取“Tnl”值(2232)。

目前,我正在使用此代码进行测试并成功获得“动态”的值,但我真的想要“Tnl”的值。

 private void mGetTnlFromXML(string oldTnl)
    {
        XDocument doc = XDocument.Load("sample.xml");

        var bt = from p in doc.Descendants()
                  where (string)p.Attribute("name") == "Dynamic"
                  select p;

        foreach (string b in bt)
        {
            if (b == oldTnl)
            {
                MessageBox.Show(b.ToString());
            }
        }
    }

类似:

private void mGetTnlFromXML(string oldTnl)
    {
        XDocument doc = XDocument.Load("sample.xml");

        var bt = from p in doc.Descendants()
                  where (string)p.Attribute("name") == "Dynamic"
                  //is there are way i can also find "Tnl" here and use 
                  //later?
                  select p; //or select "Tnl" here.

        foreach (string b in bt)
        {
            if (b == oldTnl)
            {
                //select "Tnl" value (2232)
                //use "Tnl" value (2232)
                //do something....
            }
        }
    }

提前谢谢...我还在学习 LinQ :)。


更新的 XML:

<Root>
  <Data>
    <Object class="MA" Name="Sample">
      <bist name="act">false</bist>
      <bist name="Dynamic">1234</bist>
      <bist name="Fast">false</bist>
      <bist name="plane">false</bist>
      <bist name="Tnl">2232</bist>
    </Object>
  </Data>
</Root>

【问题讨论】:

  • 所以你想要 bist 元素的值,其中 name 属性是 "Tnl" 并且存在具有 @987654328 的兄弟 bist 元素@属性值为"dynamic"?
  • 我需要动态比较,然后我会得到 Tnl。如果动态不相等或不存在,则不做任何事情。

标签: c# xml linq linq-to-xml


【解决方案1】:

在我看来你想要这个:

private void mGetTnlFromXML(string oldTnl)
{
    XDocument doc = XDocument.Load("sample.xml");
    var dynamic = doc.Root.Elements("bist").Where(x => x.Attribute("name").Value == "dynamic").First().Value;
    if (dynamic == oldTnl)
    {
        var tnl = doc.Root.Elements("bist").Where(x => x.Attribute("name").Value == "Tnl").First().Value;
        MessageBox.Show(tnl);
    };
}

这是假设您已在问题中显示了整个 XML。如果它只是较大 XML 文件的一部分,则需要显示整个文件。


鉴于您的 XML 更像这样:

<Root>
  <Data>
    <Object class="MA" Name="Sample">
      <bist name="act">false</bist>
      <bist name="Dynamic">1234</bist>
      <bist name="Fast">false</bist>
      <bist name="plane">false</bist>
      <bist name="Tnl">2232</bist>
    </Object>
  </Data>
</Root>

那么代码可能会更像这样:

private void mGetTnlFromXML(string oldTnl)
{
    XDocument doc = XDocument.Load("sample.xml");
    foreach (var element in doc.Root.Element("Data").Elements("Object"))
    {
        var dynamic = element.Elements("bist").Where(x => x.Attribute("name").Value == "dynamic").First().Value;
        if (dynamic == oldTnl)
        {
            var tnl = element.Elements("bist").Where(x => x.Attribute("name").Value == "Tnl").First().Value;
            MessageBox.Show(tnl);
        };
    }
}

【讨论】:

  • 这似乎没问题。我会试试看。谢谢。整个 xml 只是一遍又一遍地由相同的“对象”组成。
  • 我一直在“var dynamic....”上收到“序列没有元素”的错误,我认为 if 语句中的“var tnl ....”会出现相同的错误.
  • @mygtwo - 是的,这是因为您发布的 XML 不是完整的 XML。您需要提供正确的 XML 才能获得正确的代码。
  • 嗨,你是对的。您的代码有效。谢谢!我的完整 xml 文件有所不同,请参阅我在上面所做的编辑...这就是它对我不起作用的原因。
  • @mygtwo - 我已更新您的问题以在正确的位置显示 XML。您不应该更改问题以使现有答案无效,所以我所做的是在底部添加 XML。
【解决方案2】:

使用 Enigmativity 提供的 Xml,我们可以将其简化为一行 XPath:

XDocument xml = XDocument.Parse(@"
<Root>
  <Object class=""MA"" Name=""Sample"">
    <bist name = ""act"" > false </bist >
    <bist name = ""Dynamic"" > 1234 </bist >
    <bist name = ""Fast"" > false </bist >
    <bist name = ""plane"" > false </bist >
    <bist name = ""Tnl"" > 2232 </bist >
  </Object >
  <Object class= ""MA"" Name = ""Sample"" >
      <bist name = ""act"" > false </bist >
      <bist name = ""Dynamic"" > 1234 </bist >
      <bist name = ""Fast"" > false </bist >
      <bist name = ""plane"" > false </bist >
      <bist name = ""Tnl"" > 2232 </bist >
  </Object >
</Root >");

xml.XPathSelectElements("//Object[bist[@name='Dynamic']]/bist[@name='Tnl']").Dump();

意思是:

  • //Object[...] - 找到具有....的“对象”。
  • bist[@name='Dynamic'] - 属性“name”等于“Dynamic”的“bist”元素
  • /bist[...] - 然后在具有...的“对象”下获取“bist”元素。
  • @name='Tnl' - 属性“名称”等于“tnl”

【讨论】:

  • 谢谢...我会试试的。 :)
  • 嗨,这可行,但它不是解决这个特定问题的方法。再次非常感谢,我也从您的贡献中学到了... :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-12-17
  • 1970-01-01
  • 1970-01-01
  • 2011-12-24
  • 1970-01-01
  • 1970-01-01
  • 2019-10-20
相关资源
最近更新 更多