我有以下名为XDocument
的{{1}}:
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").
}
有明确的条目,计数也总是返回0而BarPlugin
始终无法创建可枚举的条目。任何人都可以向我解释为什么会这样吗? e
始终正常运行并返回FooPlugin
的插件信息。
感谢您的帮助。
答案 0 :(得分: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();
答案 1 :(得分:1)
试试这个:
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 doc Element()
:
获取具有指定XName的第一个(按文档顺序)子元素。