如何选择多个属性

时间:2017-06-01 08:43:10

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

我有以下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,获取&#34; Dynamic&#34;的值后并将它与oldTnl变量进行比较,如果相等,我想选择或得到&#34; Tnl&#34;价值(2232)。

目前,我正在使用此代码进行测试,并成功获得&#34; Dynamic&#34;但我真的想要&#34; Tnl&#34;。

的价值
 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>

2 个答案:

答案 0 :(得分:0)

在我看来,你想要这个:

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

答案 1 :(得分:0)

使用Xml提供的Enigmativity,我们可以将其减少到一行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'] - 一个“bist”元素,其中“name”等于“Dynamic”
  • /bist[...] - 然后在“对象”下面加上“bist”元素,其中包含......
  • @name='Tnl' - 属性“name”等于“tnl”