如何删除所有空的 XElements
本文关键字:XElements 何删除 删除 | 更新日期: 2023-09-27 18:37:14
这个有点棘手。假设我有这个 XmlDocument
<Object>
<Property1>1</Property1>
<Property2>2</Property2>
<SubObject>
<DeeplyNestedObject />
</SubObject>
</Object>
我想找回这个
<Object>
<Property1>1</Property1>
<Property2>2</Property2>
</Object>
由于<SubObject>
的每个孩子都是空元素,我想摆脱它。具有挑战性的是,您无法在迭代节点时删除它们。任何帮助将不胜感激。
更新 这是我最终得到的。
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);
}
如果有人对此用例感兴趣,那就是我整理的一个 ObjectFilter 项目。
它会很慢,但你可以这样做:
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());
}
为了使其更快,您可以在第一次迭代后向上浏览父节点,看看它们是否为空。
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;
}
在这里,我创建一个XML文件,其中我放置了所有xml代码。您还可以使用该XmlLoad("")
来加载 xml。这将在文件加载时工作代码。您也可以尝试使用XmlLoad。
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();
}
}
}