のすべての子ノードを削除するXmlElement
が、すべての属性を保持する方法は?
XmlElement.RemoveAllもすべての属性を削除することに注意してください。すべての子ノードを削除するためのクリーンでエレガントでパフォーマンスの高い方法は何ですか? 言い換えれば、ここでのベストプラクティスとは何ですか?
のすべての子ノードを削除するXmlElement
が、すべての属性を保持する方法は?
XmlElement.RemoveAllもすべての属性を削除することに注意してください。すべての子ノードを削除するためのクリーンでエレガントでパフォーマンスの高い方法は何ですか? 言い換えれば、ここでのベストプラクティスとは何ですか?
真に効率的なソリューションの場合:
e.IsEmpty = true;
は、最も速くて簡単なオプションです。それはあなたが要求したことを正確に行います.すべての内部テキストとネストされた要素は破棄されますが、属性は保持されます.
この解決策はもっと簡単ではないでしょうか?
while(e.FirstChild != null)
e.RemoveChild(e.FirstChild);
オプション 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);
}
}
なので上に書いた通りです