我试图剥离我的XML并只保留我需要的节点
输入XML
<Employees>
<Employee>
<EmpId>1</EmpId>
<Name>Sam</Name>
<Sex>Male</Sex>
<Address>
<Country>USA</Country>
<Zip>95220</Zip>
</Address>
<Address2>
<Country>UK</Country>
<Zip>E157JQ</Zip>
</Address2>
</Employee>
<Employee>
<EmpId>2</EmpId>
<Name>Lucy</Name>
<Sex>Female</Sex>
<Address>
<Country>USA</Country>
<Zip>95220</Zip>
</Address>
<Address2>
<Country>UK</Country>
<Zip>E184JQ</Zip>
</Address2>
</Employee>
</Employees>
我的代码如下。
private void button1_Click(object sender, EventArgs e)
{
Stream s = openFileDialog1.OpenFile();
var xDoc = XDocument.Load(s);
string keep = "EmpId,Sex,Address,Zip,Address2,Country"; \\ I can change this format
string desStr = "Employee";
string[] strArr = keep.Split(',');
var nodesToDelete = xDoc.Root.Descendants(desStr)
.SelectMany(el => el.Descendants()
.Where(a => !strArr.Contains(a.Name.ToString())));
foreach (var node in nodesToDelete.ToList())
node.Remove();
richTextBox1.Text = xDoc.ToString();
}
我从上面得到的输出是
<Employees>
<Employee>
<EmpId>1</EmpId>
<Sex>Male</Sex>
<Address>
<Country>USA</Country>
<Zip>95220</Zip>
</Address>
<Address2>
<Country>UK</Country>
<Zip>E157JQ</Zip>
</Address2>
</Employee>
<Employee>
<EmpId>2</EmpId>
<Sex>Female</Sex>
<Address>
<Country>USA</Country>
<Zip>95220</Zip>
</Address>
<Address2>
<Country>UK</Country>
<Zip>E184JQ</Zip>
</Address2>
</Employee>
</Employees>
我需要的输出是
<Employees>
<Employee>
<EmpId>1</EmpId>
<Sex>Male</Sex>
<Address>
<Zip>95220</Zip>
</Address>
<Address2>
<Country>UK</Country>
</Address2>
</Employee>
<Employee>
<EmpId>2</EmpId>
<Sex>Female</Sex>
<Address>
<Zip>95220</Zip>
</Address>
<Address2>
<Country>UK</Country>
</Address2>
</Employee>
</Employees>
如何查询Address \ Zip和Address2 \ Country我需要这是通用的(因此可以更改字符串保持)所以我不能硬编码节点名称。
由于
答案 0 :(得分:0)
这取决于你想要多少通用。 这是保持当前代码结构的一种有点过时的方式。
string keep = @"EmpId,Sex,Address,Address\Zip,Address2,Address2\Country";
string desStr = "Employee";
string[] strArr = keep.Split(',');
var nodesToDelete = xDoc.Root.Descendants(desStr)
.SelectMany(el => el.Descendants()
.Where(a =>
{
if (a.Parent.Name == desStr)
{
return !strArr.Contains(a.Name.ToString());
}
else
{
return !strArr.Contains(a.Parent.Name + @"\" + a.Name);
}
}));
foreach (var node in nodesToDelete.ToList())
node.Remove();
正确的方法是保留您想要保留的所有节点的完整路径。
答案 1 :(得分:0)
我的方式:
string keep = "Employees,Employee,EmpId,Sex,Address2,Address,Address.Zip,Address2.Country"; // I can change this format
string[] strArr = keep.Split(',');
foreach (var node in xDoc.Descendants().ToArray())
{
var path = Path(node);
if (!strArr.Any(path.EndsWith))
{
node.Remove();
}
}
var results = xDoc.ToString();
}
private static string Path(XElement x)
{
if (x.Parent != null)
{
return Path(x.Parent) + "." + x.Name;
}
return x.Name.ToString();
}