C# 如果某些其他节点不包含特定的子节点,则删除多个XML节点
我有一个复杂的xml,看起来像这样:C# 如果某些其他节点不包含特定的子节点,则删除多个XML节点,c#,xml,linq-to-xml,C#,Xml,Linq To Xml,我有一个复杂的xml,看起来像这样: <rootElement> <vElement number="0"> <!-- Next node, elB, could or could not appear --> <elB>SomeData</elB> <block> <wFormNum>0</wFormNum>
<rootElement>
<vElement number="0">
<!-- Next node, elB, could or could not appear -->
<elB>SomeData</elB>
<block>
<wFormNum>0</wFormNum>
</block>
</vElement>
<vElement number="1">
<block>
<wFormNum>1</wFormNum>
</block>
</vElement>
<vElement number="2">
<!-- Next node, elB, could or could not appear -->
<elB>SomeData</elB>
<block>
<wFormNum>0</wFormNum>
</block>
</vElement>
<vElement number="3">
<block>
<wFormNum>2</wFormNum>
</block>
</vElement>
<vElement number="4">
<block>
<wFormNum>3</wFormNum>
</block>
</vElement>
.
.
.
<wForm number="0">
</wForm>
<wForm number="1">
<kB number="0"></kB>
<kB number="1"></kB>
<kB number="2"></kB>
<kB number="3"></kB>
</wForm>
<wForm number="2">
<kB number="0"></kB>
<kB number="1"></kB>
<kB number="2"></kB>
<kB number="3"></kB>
<kB number="4"></kB>
<kB number="5"></kB>
<kB number="6"></kB>
<kB number="7"></kB>
</wForm>
<wForm number="3">
</wForm>
</rootElement>
一些数据
0
1.
一些数据
0
2.
3.
.
.
.
如您所见,元素
包含一个子元素
,该子元素也包含子元素
<代码>的值必须在
元素的属性编号中找到。因此
与
元素成对出现
如果满足某些条件,我必须从xml中删除一些
和
元素。条件如下:
- 如果元素
包含子元素
,则不会删除此子元素。成对的
元素也不会被删除
- 如果元素
不包含子元素
,并且
不包含子元素
,则将被删除李>
- 如果元素
不包含子元素
,但成对的
包含子元素
,则不会被删除
- 一个
元素可以与多个
成对出现
为了更清楚,我将从上面的xml代码示例中向您介绍必须删除的元素:
- 不能删除元素
,因为它包含子元素
。元素
也不会被删除,因为它与
成对,由0
设置
- 可以删除元素
,因为它不包含子元素
,而是与
成对,由1
设置,并且
包含类型为
的元素。因此,
和
将不会被删除
- 元素
与
相同,因此不会被删除
- 元素
与
相同,因此它不会被删除,
也不会被删除
- 元素
它将被删除,因为它不包含任何
子元素,而且
也不包含
子元素<代码>
也将被删除,因为它不包含
子项,并且与无法删除的其他
不成对
如果可能的话,我想使用Linq从一行代码中删除“可移动”节点(
和
)。我尝试了多条foreach()
指令,但由于“包含或不包含子元素”的原因,这很复杂:(
谢谢。这是我的解决方案。我更新了代码。vElement不包含EIN elb,因此您对vElement 1和wForm 1的评论是错误的,没有删除。以下内容被删除:(1)vElement 3和4(2)wForm 3。我使用的是xml linq
using System;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication9
{
class Program
{
const string FILENAME = @"c:\temp\test.xml";
static void Main(string[] args)
{
XDocument doc = XDocument.Load(FILENAME);
List<WForm> wforms = doc.Descendants("wForm")
.Select(x => new WForm() { number = (int)x.Attribute("number"), element = x })
.ToList();
var results = (from vElement in doc.Descendants("vElement")
join wForm in wforms on (int)vElement.Attribute("number") equals wForm.number into v
from wForm in v.DefaultIfEmpty()
select new { vElement = vElement, wForm = wForm }
).ToList();
foreach (var result in results)
{
if (result.vElement.Element("elB") != null)
{
if (result.wForm != null) result.wForm.delete = false;
continue;
}
else
{
if (result.wForm != null)
{
if (result.wForm.element.Element("kB") != null)
{
result.wForm.delete = false;
}
continue;
}
else
{
int number = (int)result.vElement.Attribute("number");
Console.WriteLine("Remove vElement : '{0}'", number);
result.vElement.Remove();
}
}
}
foreach (WForm wForm in wforms)
{
if (wForm.delete)
{
Console.WriteLine("Remove wForm : '{0}'", wForm.number);
wForm.element.Remove();
}
}
Console.ReadLine();
}
}
public class WForm
{
public int number { get; set; }
public bool delete = true;
public XElement element { get; set; }
}
}
使用系统;
使用制度;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用System.Xml;
使用System.Xml.Linq;
命名空间控制台应用程序9
{
班级计划
{
常量字符串文件名=@“c:\temp\test.xml”;
静态void Main(字符串[]参数)
{
XDocument doc=XDocument.Load(文件名);
列表wforms=文档子体(“wForm”)
.Select(x=>newWForm(){number=(int)x.Attribute(“number”),element=x})
.ToList();
var结果=(来自文档子体中的VELENT(“VELENT”)
在(int)vElement.Attribute(“number”)上的wforms中加入wForm等于wForm.number到v中
来自v.DefaultIfEmpty()中的wForm
选择新{VELENT=VELENT,wForm=wForm}
).ToList();
foreach(结果中的var结果)
{
if(result.velment.Element(“elB”)!=null)
{
如果(result.wForm!=null)result.wForm.delete=false;
继续;
}
其他的
{
如果(result.wForm!=null)
{
if(result.wForm.element.element(“kB”)!=null)
{
result.wForm.delete=false;
}
继续;
}
其他的
{
int number=(int)result.vElement.Attribute(“number”);
WriteLine(“Remove vElement:'{0}',number);
result.vElement.Remove();
}
}
}
foreach(WForm WForm in WForm)
{
if(wForm.delete)
{
WriteLine(“删除wForm:'{0}',wForm.number);
element.Remove();
}
}
Console.ReadLine();
}
}
公共类WForm
{
公共整数{get;set;}
公共bool delete=true;
公共XElement元素{get;set;}
}
}
我不认为这是答案,因为我试图找到的是不同的,一个LINQ版本,有一个简短而漂亮的可见代码,但这是我要做和工作的,并且尊重这一声明:
private static void RemoveEmptyWForms(string filePath, string vN, string rPN) {
XDocument xml = XDocument.Load(filePath);
List<wForm> listWForms = new List<wForm>();
List<Elements> listElements = new List<Elements>();
if (xml.Descendants("vElement").Count() == 0)
{
Console.WriteLine("File does not contains elements of type \"vElement\"!");
return;
}
else
{
foreach (XElement xe in xml.Descendants("vElement"))
{
Elements el = new Elements();
el.PNV = rPN + " | " + vN;
el.Node = xe;
el.Value = xe.Attribute("number").Value;
listElements.Add(el);
}
}
foreach (XElement xw in xml.Descendants("wForm"))
{
string value = xw.Attribute("number").Value;
wForm wfn = new wForm();
wfn.PNV = rPN + " | " + vN;
wfn.Node = xw;
wfn.Value = value;
if (xw.Descendants("kB").Count() > 0)
{
wfn.CanBeDeleted = false;
listWForms.Add(wfn);
continue;
}
wfn.CanBeDeleted = true;
listWForms.Add(wfn);
foreach (XElement xe in xml.Descendants("vElement")) {
if (xe.Descendants("elB").Count() > 0)
{
foreach (Elements el in listElements)
{
if (el.Node != xe) continue;
else {
el.CanBeDeleted = false;
break;
}
}
}
else {
string xeWfn = xe.Element("block").Element("wFormNum").Value;
foreach (wForm wf in listWForms) {
if (wf.Value.Equals(xeWfn))
{
if (wf.CanBeDeleted == false)
{
foreach (Elements el in listElements)
{
if (el.Node != xe) continue;
else
{
el.CanBeDeleted = false;
break;
}
}
break;
}
foreach (Elements el in listElements)
{
if (el.Node != xe) continue;
else
{
el.CanBeDeleted = true;
break;
}
}
}
}
}
}
}
foreach (wForm wf in listWForms) {
if (wf.CanBeDeleted) {
wf.Node.Remove();
Console.WriteLine("Removing wForm {0} from v {1}", wf.Value, wf.PNV);
}
}
foreach (Elements el in listElements) {
if (el.CanBeDeleted) {
el.Node.Remove();
Console.WriteLine("Removing element {0} from v {1}", el.Value, el.PNV);
}
}
}
class WaveForm {
public string PNV { get; set; }
public XNode Node { get; set; }
public string Value { get; set; }
public bool CanBeDeleted { get; set; } = true;
}
class Elements {
public string PNV{ get; set; }
public XNode Node { get; set; }
public string Value { get; set; }
public bool CanBeDeleted { get; set; } = true;
}
private static void removeMptyForms(字符串文件路径、字符串vN、字符串rPN){
XDocument xml=XDocument.Load(文件路径);
锂
XElement Cleanup(XElement element)
{
var clean = new XElement(element);
var nonEmptyForms = clean.XPathSelectElements("//wForm[*]")
.Select(f => (int)f.Attribute("number"))
.ToHashSet();
clean.XPathSelectElements("//vElement")
.Where(e => !e.Elements("elB").Any())
.Where(e => !nonEmptyForms.Contains((int)e.XPathSelectElement("block/wFormNum")))
.Remove();
return clean;
}