18

のすべての子ノードを削除するXmlElementが、すべての属性を保持する方法は?

XmlElement.RemoveAllもすべての属性を削除することに注意してください。すべての子ノードを削除するためのクリーンでエレガントでパフォーマンスの高い方法は何ですか? 言い換えれば、ここでのベストプラクティスとは何ですか?

4

3 に答える 3

31

真に効率的なソリューションの場合:

e.IsEmpty = true;

は、最も速くて簡単なオプションです。それはあなたが要求したことを正確に行います.すべての内部テキストとネストされた要素は破棄されますが、属性は保持されます.

于 2014-03-27T09:24:45.050 に答える
6

この解決策はもっと簡単ではないでしょうか?

while(e.FirstChild != null)
    e.RemoveChild(e.FirstChild);
于 2013-09-05T13:04:05.550 に答える
3

オプション 1elem.InnerXml = "";これが必要な場合は、完全な作業コード を使用します。

    var doc = new XmlDocument();
    doc.LoadXml("<x a1='a' a2='b'><child1/><child2/></x>");
    var elem = doc.DocumentElement;

    Console.WriteLine(elem.OuterXml);
    Console.WriteLine("HasAttributes " + elem.HasAttributes);
    Console.WriteLine("HasChildNodes " + elem.HasChildNodes);

    elem.InnerXml = "";
    Console.WriteLine(elem.OuterXml);
    Console.WriteLine("HasAttributes " + elem.HasAttributes);
    Console.WriteLine("HasChildNodes " + elem.HasChildNodes);
    Console.ReadLine();

InnerXml の詳細情報:

    public override string InnerXml
    {
      get
      {
        return base.InnerXml;
      }
      set
      {
        this.RemoveAllChildren();
        new XmlLoader().LoadInnerXmlElement(this, value);
      }
    }

LoadInnerXmlElement でパフォーマンスの問題が発生する可能性がありますが、空の文字列があるため、大きくなることはありません。ほとんどの場合、このメソッドが必要になるためです。

internal XmlNamespaceManager ParsePartialContent(XmlNode parentNode, string innerxmltext, XmlNodeType nt)
    {
      this.doc = parentNode.OwnerDocument;
      XmlParserContext context = this.GetContext(parentNode);
      this.reader = this.CreateInnerXmlReader(innerxmltext, nt, context, this.doc);
      try
      {
        this.preserveWhitespace = true;
        bool isLoading = this.doc.IsLoading;
        this.doc.IsLoading = true;
        if (nt == XmlNodeType.Entity)
        {
          XmlNode newChild;
          while (this.reader.Read() && (newChild = this.LoadNodeDirect()) != null)
            parentNode.AppendChildForLoad(newChild, this.doc);
        }
        else
        {
          XmlNode newChild;
          while (this.reader.Read() && (newChild = this.LoadNode(true)) != null)
            parentNode.AppendChildForLoad(newChild, this.doc);
        }
        this.doc.IsLoading = isLoading;
      }
      finally
      {
        this.reader.Close();
      }
      return context.NamespaceManager;
    }

オプション 2 次のコード:

    XmlNode todelete = elem.FirstChild;
    while (todelete != null)
    {
        elem.RemoveChild(elem.FirstChild);
        todelete = elem.FirstChild;
    }

パフォーマンについて。XmlElement.RemoveAll() を見てみましょう:

public override void RemoveAll()
{
  base.RemoveAll();
  this.RemoveAllAttributes();
}

base.RemoveAll() は正確には次のとおりです。

[TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")]
public virtual void RemoveAll()
{
  XmlNode oldChild = this.FirstChild;
  for (; oldChild != null; {
    XmlNode nextSibling;
    oldChild = nextSibling;
  }
  )
  {
    nextSibling = oldChild.NextSibling;
    this.RemoveChild(oldChild);
  }
}

なので上に書いた通りです

于 2013-04-10T12:32:59.797 に答える