2013-04-10 18 views

cevap

25

:

e.IsEmpty = true; 

en hızlı ve en basit seçenektir. İstediğiniz şeyi tam olarak yapar: nitelikler korunurken tüm iç metin ve iç içe geçmiş öğeler atılır.

+0

Bu, beklediğim çözüm! Reflector'u kullanarak bu özelliğin tam olarak istenen şeyi yaptığını doğruladım. – usr

4

Seçenek 1 Kullanım elem.InnerXml = ""; tam çalışma kodu gerekirse bu:

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(); 
yapmak InnerXml neler

Detailied bilgi:

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

LoadInnerXmlElement üzerinde ama çünkü biz performans sorun olabilir boş dize var, büyük olmamalıdır çünkü çoğu zaman bu yöntemi alır:

kod takiben
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; 
    } 

Seçenek 2 : performane Hakkında

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

.

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

Nerede:

[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); 
    } 
} 

Ben

+1

Bunun için performans ile ilgili çekincelerim var. Ayrıca hacky hissediyor. XML belgesini, bir dize düzeyinde değil, AST düzeyinde ele almak istiyorum. – usr

+0

Ayrıntılı bilgi eklendi –

+0

Ok teşekkürler! Bunu bir uzatma yöntemine koyacağım ve sorun şimdi tüm zamanlar için iyi çözüldü. – usr

4

misiniz bu çözüm değil yukarıda yazdığım gibi Yani aynı öyle) (en XmlElement.RemoveAll içine bakalım daha basit olmak mı? Gerçekten verimli çözüm için

while(e.FirstChild != null) 
    e.RemoveChild(e.FirstChild); 
+0

Böyle yaptım. XmlNode.RemoveAll'in ne yaptığını kopyaladım. – usr

İlgili konular