2012-06-15 34 views
7

Bu biraz zor. Ben geri <SubObject> çocuklarının her ondan kurtulmak için bütün istediğim boş elemanlar olduğundan buTüm boş XElements'lar nasıl kaldırılır

<Object> 
    <Property1>1</Property1> 
    <Property2>2</Property2> 
</Object> 

almak istiyorum

<Object> 
    <Property1>1</Property1> 
    <Property2>2</Property2> 
    <SubObject> 
     <DeeplyNestedObject /> 
    </SubObject> 
</Object> 

bu XmlDocument olduğunu düşünelim. Bunu zorlaştıran şey, düğümleri üzerinde yinelediğiniz sırada kaldıramayacağınızdır. Herhangi bir yardım çok takdir edilecektir.

UPDATE İşte ben neyle sarıldım. Herkes bunun için kullanılması durumunda ilgilenen varsa

public XDocument Process() 
{ 
    //Load my XDocument 
    var xmlDoc = GetObjectXml(_source); 

    //Keep track of empty elements 
    var childrenToDelete = new List<XElement>(); 

    //Recursively iterate through each child node 
    foreach (var node in xmlDoc.Root.Elements()) 
     Process(node, childrenToDelete); 

    //An items marked for deletion can safely be removed here 
    //Since we're not iterating over the source elements collection 
    foreach (var deletion in childrenToDelete) 
     deletion.Remove(); 

    return xmlDoc; 
} 

private void Process(XElement node, List<XElement> elementsToDelete) 
{ 
    //Walk the child elements 
    if (node.HasElements) 
    { 
     //This is the collection of child elements to be deleted 
     //for this particular node 
     var childrenToDelete = new List<XElement>(); 

     //Recursively iterate each child 
     foreach (var child in node.Elements()) 
      Process(child, childrenToDelete); 

     //Delete all children that were marked as empty 
     foreach (var deletion in childrenToDelete) 
      deletion.Remove(); 

     //Since we just removed all this nodes empty children 
     //delete it if there's nothing left 
     if (node.IsEmpty) 
      elementsToDelete.Add(node); 
    } 

    //The current leaf node is empty so mark it for deletion 
    else if (node.IsEmpty) 
     elementsToDelete.Add(node); 
} 

ben araya bir ObjectFilter projesi için.

+0

Yapılandırma dosyasını okumak için System.Xml dosyasını kullanın –

+4

@sarooptrivedi: Soruyu okuyun. – SLaks

+0

@SLaks: Projeme aynı şeyleri uyguluyorum. XMLDOcument dosyasını okuyabilir ve ardından dosyayı güncelleyebilir ve son –

cevap

9

Oldukça yavaş olacak, ancak bunu:

XElement xml; 
while (true) { 
    var empties = xml.Descendants().Where(x => x.IsEmpty && !x.HasAttributes).ToList(); 
    if (empties.Count == 0) 
     break; 

    empties.ForEach(e => e.Remove()); 
} 

daha hızlı çalışmasını sağlamak için, ilk yineleme sonra üst düğümleri yürümek ve içlerinin boş olduğunu eğer görebiliyordu.

XElement xml; 
var empties = xml.Descendants().Where(x => x.IsEmpty && !x.HasAttributes).ToList(); 
while (empties.Count > 0) { 
    var parents = empties.Select(e => e.Parent) 
         .Where(e => e != null) 
         .Distinct() //In case we have two empty siblings, don't try to remove the parent twice 
         .ToList(); 

    empties.ForEach(e => e.Remove()); 

    //Filter the parent nodes to the ones that just became empty. 
    parents.RemoveAll(e => e.IsEmpty && !e.HasAttributes); 
    empties = parents; 
} 
+0

Yardım için teşekkürler! – Micah

+0

Aynı problemi yaşadım ve bu çözüm sadece bazı elementleri kaldırarak boş dize değerleri bıraktı. Bu değişiklik yardımcı oldu: var var = xml.Descendants(). (X => (x.IsEmpty || string.IsNullOrEmpty (x.Value)) &&! X.HasAttributes) .List(); ' – user5226582

-1

Burada, tüm xml kodunu koyduğum bir XML dosyası oluşturuyorum. Xml'yi yüklemek için XmlLoad("")'u da kullanabilirsiniz. Bu dosya yükleme ile kod çalışır. XmlLoad ile de deneyebilirsiniz.

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Xml; 

namespace Test 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      XmlDocument doc = new XmlDocument(); 
      doc.Load("Test.xml"); 
      XmlElement root = doc.DocumentElement; 
      foreach (var item in root) 
      { 
       XmlElement elem = (XmlElement)item; 
       if (elem.InnerText.Equals("")) 
       { 
        foreach (var child in elem.ChildNodes) 
        { 
         XmlElement childelem = (XmlElement)child; 
         childelem.RemoveAll(); 
        } 

        elem.ParentNode.RemoveChild(elem); 
       } 
      } 
      doc.Save("Test.xml"); 
      Console.ReadLine(); 
     } 
    } 
} 
İlgili konular