【问题标题】:I'm confused by Linq XML query我对 Linq XML 查询感到困惑
【发布时间】:2012-11-28 16:08:20
【问题描述】:

这是我的 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());

求帮助。

【问题讨论】:

    标签: c# xml linq


    【解决方案1】:

    我认为你让这变得比你需要的更复杂。我想你只需要:

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

    诚然,这将选择 first 匹配元素。那么query 的类型就是XElement;如果你去掉FirstOrDefault() 部分,它将返回一个IEnumerable&lt;XElement&gt;,用于所有匹配的元素。

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

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

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

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

    【讨论】:

    • x.Element(..) 之后不需要.Value 吗?
    • @CodingGorilla:要获取字符串值,是的。 OP 的原始代码只获取 XElement,所以我也是这样做的。将编辑以提供其他选项。
    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

      你快到了

      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 元素。根据示例,如果没有任何其他元素也没关系,但我个人会限制它。
      【解决方案4】:
       var q = from s in doc.Descendants("System")  
               where (int)s.Element("ID") == 123        
               select (int)s.Element("SystemSetting");
      

      并显示结果(q 将有 IEnumerable&lt;int&gt; 类型):

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

      【讨论】:

        【解决方案5】:

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

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

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

        然后找到您的 System 元素,该元素具有 123 的子 ID 元素。

        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; 定义的

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-11-18
          • 1970-01-01
          相关资源
          最近更新 更多