【问题标题】:Linq never finding element in XDocumentLinq 从未在 XDocument 中找到元素
【发布时间】:2013-01-21 20:34:42
【问题描述】:

我有以下XDocument 称为XDoc

<?xml version="1.0" encoding="utf-8"?>
   <DatabaseList>
      <Database DatabaseName="c2501_data">
      <Plugin PluginName="FooPlugin" LastRun="1/21/2013 3:22:08 PM" />
      <Plugin PluginName="SpecialPlugin" LastRun="2013-01-21T15:22:09.3791103-05:00" />
      <Plugin PluginName="BarPlugin" LastRun="2013-01-21T15:23:13.0964814-05:00" />
   </Database>
</DatabaseList>

我正在编写一个程序,用于搜索插件上次在数据库上运行的时间(如果有的话)。我使用以下两段代码来确定数据库上的插件是否存在条目:

        var h = (from el in XDoc.Root.Elements("Database")
                 where el.Element("Plugin").Attribute("PluginName").Value=="FooPlugin" 
                 && el.Attribute("DatabaseName").Value=="c2501_data"
                 select el.Element("Plugin"));

        var e = (from el in XDoc.Root.Elements("Database")
                 where el.Element("Plugin").Attribute("PluginName").Value=="BarPlugin"
                 && el.Attribute("DatabaseName").Value == "c2501_data"
                 select el.Element("Plugin"));


        if ((from el in XDoc.Root.Elements("Database")
             where el.Element("Plugin").Attribute("PluginName").Value == "BarPlugin"
             && el.Attribute("DatabaseName").Value == "c2501_data"
             select el.Element("Plugin")).Count() == 0)
        {
            XElement SpecialPlugin = new XElement("Plugin",
                new XAttribute("PluginName", "BarPlugin"),
                new XAttribute("LastRun", DateTime.Now));

            var CurNode = from node in XDoc.Root.Elements("Database")
                          where (string)node.Attribute("DatabaseName").Value == "c2501_data"
                          select node;

            foreach (var node in CurNode)
                node.Add(SpecialPlugin);

            XDoc.Save(RuntimesPath);
            //XDoc.Root.Elements("Database").Attribute("DatabaseName").
        }

我遇到的问题是,即使显然有 BarPlugin 的条目,计数将始终返回 0,而 e 将始终无法创建可编号。谁能向我解释为什么会这样? FooPlugin 始终正常工作并返回 h 的插件信息。

感谢您的帮助。

【问题讨论】:

    标签: c# xml linq-to-xml


    【解决方案1】:

    您正在选择一个Database 元素,其中包含一个名为Plugin 的具有给定名称的子元素。由于您只有一个 Database 元素,因此每次都会获得相同的外部元素。然后,您获取该数据库元素并返回第一个 Plugin 子元素,在这种情况下,它将始终是 Foo。您需要找到合适的Database 元素,然后查询每个子元素,以便您可以返回它们:

    public static XElement GetPlugin(XDocument XDoc, string databaseName, string pluginName)
    {
        var h = from database in XDoc.Root.Elements("Database")
                where database.Attribute("DatabaseName").Value == databaseName
                from plugin in database.Elements("Plugin")
                where plugin.Attribute("PluginName").Value == pluginName
                select plugin;
    
        return h.FirstOrDefault();
    }
    

    或者,如果您愿意,在方法语法中:

    var q = XDoc.Root.Elements("Database")
        .Where(db => db.Attribute("DatabaseName").Value == databaseName)
        .SelectMany(db => db.Elements("Plugin"))
        .Where(plugin => plugin.Attribute("PluginName").Value == pluginName);
    
    return q.FirstOrDefault();
    

    【讨论】:

      【解决方案2】:

      试试这个:

      var db = XDoc.Root.Elements("Database");
      var z = (from el in db.Elements("Plugin")
              where el.Attribute("PluginName").Value == "BarPlugin"
                    && el.Parent.Attribute("DatabaseName").Value == "c2501_data"
                    select el).FirstOrDefault();
      if(z != null)
          .....
      

      我正在使用Elements() 方法来获取所有子元素,并使用Parent 属性来查找父元素“DatabaseName”

      您的代码中的问题是您的el.Element() 仅搜索第一个元素,因此它只能找到“FooPlugin”,它位于 xml 中的第一个位置。

      来自 MSDN 文档Element()

      获取第一个(按文档顺序)具有指定 XName 的子元素。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-01-17
        • 2020-03-29
        • 1970-01-01
        • 2011-01-24
        • 1970-01-01
        • 2021-07-22
        • 2012-06-15
        相关资源
        最近更新 更多