2

指定された xpath (または階層位置を識別する他の方法) に対して、ノードが存在しない場合にノードが作成される XML ノードを作成/更新するために使用できる方法はありますか? 親ノードが存在しない場合は、これを作成する必要があります。すべての可能なノードを含む XSD があります。

すなわち前に:

<employee>
   <name>John Smith</name>
</employee>

次のようなものを呼び出したい:

CoolXmlUpdateMethod("/employee/address/city", "Los Angeles");

後:

  <employee>
       <name>John Smith</name>
       <address>
         <city>Los Angeles</city>
       </address>
    </employee>

または、xpath を指定してノードを作成する方法で、親ノードが存在しない場合は再帰的に作成しますか?

アプリケーションに関する限り (重要な場合)、これはデータが取り込まれたノードのみを含む既存の XML ドキュメントを取得し、別のシステムからそれにデータを追加します。新しいデータには、ソース XML に値が入力されている場合とされていない場合があります。

確かにこれは珍しいシナリオではありませんか?

4

4 に答える 4

2

さて、私たちが行うことは、XMLを表すクラスを作成することです(XSD2Codeを使用してXSDからクラスを生成します)。それが逆シリアル化/シリアル化されると、そのようなことを実行できます(XMLSerializer)。

于 2012-07-05T19:01:18.637 に答える
1

私は以前にこのようなことをしました。LINQ to XML を使用しています。ノード名のキューと、リストの最後のノードの値を受け取る XElement の拡張メソッドを作成しました。私が作成した拡張メソッドは次のとおりです。

/// <summary>
    /// Creates nessecary parent nodes using the provided Queue, and assigns the value to the last child node.
    /// </summary>
    /// <param name="ele">XElement to take action on</param>
    /// <param name="nodes">Queue of node names</param>
    /// <param name="value">Value for last child node</param>
    public static void UpdateOrCreate(this XElement ele, Queue<string> nodes, string value)
    {
        string previousNodeName = "";
        int fullQueueCOunt = nodes.Count;
        for (int i = 0; i < fullQueueCOunt; i++)
        {
            string node = nodes.Dequeue();
            if (ele.Descendants(node).FirstOrDefault() == null)
            {
                if (!string.IsNullOrEmpty(previousNodeName))
                {
                    ele.Element(previousNodeName).Add(new XElement(node));
                }
                else
                {
                    // use main parent node if this is the first iteration
                    ele.Add(new XElement(node));
                }
            }
            previousNodeName = node;
        }
        // assign the value of the last child element
        ele.Descendants(previousNodeName).First().Value = value;
    }

そして、ここにサンプル実装があります:

XElement element = XElement.Parse(
                "<employee>" +
                   "<name>John Smith</name>" +
                "</employee>");
            Queue<string> nodeQueue = new Queue<string>();
            nodeQueue.Enqueue("address");
            nodeQueue.Enqueue("city");
            element.UpdateOrCreate(nodeQueue, "myValue");

これにより、入力 XML が取得されます。

<employee>
  <name>John Smith</name>
</employee>

それを次のように変更します。

<employee>
  <name>John Smith</name>
  <address>
    <city>myValue</city>
  </address>
</employee>

これは、'address' ノードや 'city' ノードが既に存在する場合にも機能します。

于 2012-07-05T21:13:36.517 に答える
0

私は自分でこれに苦労したので、C#を使用して.Net2.0で動作する答えを追加したいと思いました。

private static void addOrUpdateNode(XmlDocument xmlDoc, string xpath, string value)
{
    XmlNode node = xmlDoc.SelectSingleNode(xpath);
    if (node == null)
    {
        //node does not exist, so create it
        string newNodeString = String.Format(
            "<city>{0}</city>", value); //as per OP's example
        StringReader sr = new StringReader(newNodeString);
        XmlTextReader reader = new XmlTextReader(sr);
        XmlNode newNode = xmlDoc.ReadNode(reader);
        //adding to root of document, you may want to
        //navigate to a different part of the doc
        xmlDoc.AppendChild(newNode);
    }
    else
    {
        node.Value = value;
    }
}

それをかなりラフでテストされていないままにしておくことを許してください、それをクリーンアップしたい人は誰でも気軽に編集してください。

于 2012-07-31T09:45:07.867 に答える