0

たとえば、XML ドキュメントがある場合

<root a="value">
    <item name="first">
        x
        <foo name = "firstgrandchild">There is nothing here</foo>
        y
        <foo name = "secondgrandchild">There is something here</foo> 
    </item>
    <item name="second">
        xy
        <foo/>
        ab
    </item>
</root>

最初にノード「item」の最初の出現を見つけてから属性を更新し、次にノード「foo」の最初の出現を更新してから属性を更新したいなど、

私のコードは以下の通りです

myDoc.Load("Items2.xml");
myNode = myDoc.DocumentElement;
mySearchNode = myNode.SelectSingleNode("/root/item");
mySearchNode.Attributes["name"].Value = "Joel";
Console.WriteLine(mySearchNode.OuterXml);
mySearchChildNode = mySearchNode.SelectSingleNode("/item/foo");
Console.WriteLine(mySearchChildNode.OuterXml);

属性の最初の検索と更新は正常に機能しますが、mySearchNode.SelectSingleNode が null を返すため、2 番目の検索と更新は失敗します。

質問 - このコードに根本的に間違っている点はありますか? SelectSingleNode が 2 番目のインスタンスで期待どおりに機能しないのはなぜですか。これに関する限り、Element 型の XmlNode で実行しています。

よろしくお願いします。

どうもありがとう、

4

4 に答える 4

5

2番目のXPathクエリには、先頭にスラッシュを付けないでください。/は「ドキュメントのルート」を意味します。スラッシュを省略すると、クエリはmySearchNode変数に相対的になります。また、「item」を再度含めるべきではありません。クエリは、選択した「item」ノードに関連しています。コード内:

myDoc.Load("Items2.xml");
myNode = myDoc.DocumentElement;
mySearchNode = myNode.SelectSingleNode("/root/item");
mySearchNode.Attributes["name"].Value = "Joel";
Console.WriteLine(mySearchNode.OuterXml);
mySearchChildNode = mySearchNode.SelectSingleNode("foo");
Console.WriteLine(mySearchChildNode.OuterXml);
于 2009-06-14T16:00:07.243 に答える
2

mySearchNodeはitemノードであるため、が2番目のxpathfooの子である場合は、単に次のようになります。item"foo"

于 2009-06-14T16:00:05.823 に答える
0

SelectNodes を実行してから、すべての項目ノードをループできます。項目ごとに、さらに foo ノードで SelectNodes を実行する必要があります。ノード数と、item ノードと foo ノードの両方の属性名が存在するかどうかを確認する必要があります。次のコードを使用できます。

/// <summary>
/// Changes the xml in sourceFileName and writes the changed xml to destFileName
/// </summary>
public static void ProcessNames(string sourceFileName, string destFileName)
{
    XmlDocument xmlDoc = new XmlDocument();
    XmlTextWriter xtw = null;
    xmlDoc.Load(sourceFileName);

    try
    {
        // Parse through all the item nodes and process them
        XmlNodeList itemList = xmlDoc.SelectNodes("//root/item");

        if (itemList.Count > 0)
        {
            foreach (XmlNode item in itemList)
            {
                // Change the name attribute, if it exists
                if (item.Attributes["name"] != null)
                {
                    string newItemName = item.Attributes["name"].Value + "Joel";
                    item.Attributes["name"].Value = newItemName;
                }

                // Parse through all the foo nodes and process them
                XmlNodeList fooList = item.SelectNodes("foo");

                if (fooList.Count > 0)
                {
                    foreach (XmlNode foo in fooList)
                    { 
                        // Change the name attribute, if it exists
                        if (foo.Attributes["name"] != null)
                        {
                            string newFooName = foo.Attributes["name"].Value + "Joel";
                            foo.Attributes["name"].Value = newFooName;
                        }
                    }
                }

            }

            xtw = new XmlTextWriter(destFileName, Encoding.UTF8);
            xmlDoc.WriteContentTo(xtw);
        }

    }
    finally
    {
        xtw.Close();
    }
}
于 2009-06-15T09:57:42.623 に答える