2

私は次のように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>

データベースでプラグインが最後に実行されたのがいつであったかを検索するプログラムを作成しています。次の 2 つのコードを使用して、データベースにプラグインのエントリが存在するかどうかを確認します。

        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常に enumberable を作成できないことです。誰かが私にこれがなぜなのか説明できますか? FooPluginは常に正しく動作し、のプラグイン情報を返しますh

助けてくれてありがとう。

4

2 に答える 2

1

特定の名前でDatabase呼び出された子要素を含む要素を選択しています。Plugin要素が 1 つしかないため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();
于 2013-01-21T20:41:57.483 に答える
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()、最初の要素のみを検索しているため、xml の最初の位置にある「FooPlugin」しか見つからないことです。

MSDN doc からElement():

指定された XName を持つ最初 (ドキュメント順) の子要素を取得します。

于 2013-01-21T20:47:55.150 に答える