我对Linq XML查询感到困惑

4

这是我的XML示例。如果 ID = 123,我想要选择SystemSetting的值。但我不知道该如何做。如果ID的值等于123,我该如何选择SystemSetting的值?

<?xml version="1.0" encoding="utf-8" ?>
<Private>
  <System>
    <ID>123</ID>
    <NAME>Test</NAME>
    <SystemSetting>128</SystemSetting>
    <SystemSettingCS>127</SystemSettingCS>
  </System> 
  <System>
    <ID>124</ID>
    <NAME>Test2</NAME>
    <SystemSetting>128</SystemSetting>
    <SystemSettingCS>127</SystemSettingCS>
  </System>
  <System>
    <ID>0</ID>
    <NAME>Test</NAME>   
    <SystemSetting>5</SystemSetting>
    <SystemSettingCS>250</SystemSettingCS>
  </System>
</Private>

以下是我尝试过的方法:

    var doc = XDocument.Load(Application.StartupPath+  @"\Settings.xml");
    var q = from Ana in doc.Descendants("Private")                   
            from sistem in Ana.Elements("System")                   
            where (int)sistem.Element("ID") == 123
            from assetText in Sistem.Elements("System")
            select assetText.Element("SystemSetting");

    MessageBox.Show(q.ToString());

谢谢你的帮助。
5个回答

2

我认为你把这个问题想得比必要的复杂。我认为你只需要:

var query = doc.Descendants("Private") // Or just doc.Root
               .Elements("System")
               .Where(x => (int) x.Element("ID") == 123)
               .Select(x => x.Element("SystemSetting"))
               .FirstOrDefault();

那会选择第一个匹配的元素,诚然。类型化的queryXElement; 如果你去掉 FirstOrDefault() 部分,它将为所有匹配的元素返回IEnumerable<XElement>

如果您只想要值而不是元素,则可以更改Select为:

.Select(x => (string) x.Element("SystemSetting"))

或者

.Select(x => x.Element("SystemSetting").Value)

(如果没有 SystemSetting 元素,第一个将返回 null ;第二个将抛出异常。)

1
x.Element(..) 后面不是需要加上 .Value 吗? - CodingGorilla
@CodingGorilla:要获取字符串值,是的。OP的原始代码只获取了XElement,所以我也这样做了。不过我会编辑以提供其他选项。 - Jon Skeet

1

Xpath(System.Xml.XPath)在这里确实可以帮上大忙。

var system = doc.XPathSelectElement("//System[ID[text()='123']]");
var val = system.Element("SystemSetting").Value;

或者用一行代码

var s = (string)doc.XPathSelectElement("//System[ID[text()='123']]/SystemSetting");

0

你快到了

var xmlFile = XElement.Load(@"c:\\test.xml");

var query =
  from e in xmlFile.Elements()
  where e.Element("ID").Value == "123"
  select e.Element("SystemSetting").Value;

请注意,这不会限制为“System”元素。如果没有其他元素,就像示例一样,那么也没关系,但我个人会进行限制。 - Jon Skeet

0

这是一个Linq问题,但是有一种替代的XPath方法,但是下面定义的类可以在任何情况下使用。

定义一个从父System元素读取的类:

public class XSystem
{
   public XSystem(XElement xSystem) { self = xSystem; }
   XElement self;

   public int Id { get { return (int)self.Element("ID"); } }
   public string Name { get { return self.Element("NAME").Value; } }
   public int SystemSetting { get { return (int)self.Element("SystemSetting"); } }
   public int SystemSettingCS { get { return (int)self.Element("SystemSettingCS"); } }
}

然后找到具有子元素ID123System元素。

int id = 123;
string xpath = string.Format("//System[ID={0}", id);
XElement x = doc.XPathSelectElement(xpath);

然后将其插入到类中:

XSystem system = new XSystem(x);

然后读取您想要的值:

int systemSetting = system.SystemSetting; 

XPath 是通过 using System.Xml.XPath; 定义的。


0
 var q = from s in doc.Descendants("System")  
         where (int)s.Element("ID") == 123        
         select (int)s.Element("SystemSetting");

并显示结果(q 将具有 IEnumerable<int> 类型):

if (q.Any())
    MessageBox.Show("SystemSettings = " + q.First());
else
    MessageBox.Show("System not found");

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接