C# XDocument 删除不在列表中的属性
C# XDocument remove attributes not in a list
我在 C# 中查询 Web 服务,它 returns XML,我已将其解析为 XDocument。我删除了一个无关的节点,该节点 returns 关于服务调用的统计信息,剩下的是这样的:
<xml>
<element attr1="1" attr2="2" attr3="3" attr4="4" ... attrN="N" />
<element attr1="a" attr2="b" attr3="c" ... attrN="N" />
...
<element attr1="!" attr2="?" attr3=":" attr4="" ... attrN="N />
</xml>
我真的只对检索 attr2 和 attr3 感兴趣,所以我想删除所有其他属性以结束此操作:
<xml>
<element attr2="2" attr3="3" />
<element attr2="b" attr3="c" />
...
<element attr2="?" attr3=":" />
</xml>
但是,这是我正在使用的相关代码,它只删除了 attr1:
String[] WS_LookupFields = "attr2,attr3".Split(',');
var output = XDocument.Parse(WS_Output_Raw);
output.Descendants("system").Remove(); //removes query statistics
foreach (XAttribute attribute in output.Descendants("element").Attributes())
{
if (!Array.Exists<String>(WS_LookupFields, fieldname => attribute.Name == fieldname)) attribute.Remove();
}
问题在于foreach 仅 returns attr1 而不是attr1 通过attrN。有什么建议吗?
我想你需要两个循环:
// Loop all descendants
foreach (var element in output.Descendants("element"))
{
// for that element, loop all attributes
foreach (var attribute in element.Attributes())
{
if (!Array.Exists<String>(WS_LookupFields, fieldname => attribute.Name ==
fieldname)) attribute.Remove();
}
}
只需创建具有所需属性的新文档
var required = new HashSet<string> { "attr2", "attr3" };
var elements = original.Descendants("element").Select(element =>
{
var attributes = element.Attributes().Where(a => required.Contains(a.Name.LocalName));
return new XElement(element.Name, attributes);
});
var root = new XElement(original.Root.Name, elements);
var newDocument = new XDocument(original.Declaration, root);
使用这个:
var WS_LookupFields = "attr2,attr3".Split(',').ToList();
var output = XDocument.Parse(WS_Output_Raw);
foreach (var loElement in output.Descendants("element"))
{
//loElement.Attributes()
// .Where(item => !WS_LookupFields.Any(name => item.Name == name))
// .ToList()
// .ForEach(item => item.Remove());
//UPDATE: Charles Mager
loElement.Attributes()
.Where(item => !WS_LookupFields.Any(name => item.Name == name))
.Remove();
}
或者:
foreach (var loAttribute in output.Descendants("element").Attributes().ToList())
{
if (!WS_LookupFields.Contains(loAttribute.Name.ToString()))
loAttribute.Remove();
}
只需将 ToArray() 方法添加到您的 foreach 循环中:
foreach (XAttribute attribute in output.Descendants("element").Attributes().ToArray())
{
if (!Array.Exists<String>(WS_LookupFields, fieldname => attribute.Name == fieldname)) attribute.Remove();
}
有一些方法旨在从树中删除 xml 内容。您已经将一个用于 Element
s,将另一个用于属性。
建立查询以select您要删除的属性,然后删除它们。
var attrs = new HashSet<string>("attr2,attr3".Split(','));
foreach (var e in output.Descendants("element"))
e.Attributes().Where(a => !attrs.Contains(a.Name.LocalName)).Remove();
// or simply
output.Descendants("element")
.Attributes()
.Where(a => !attrs.Contains(a.Name.LocalName))
.Remove();
我在 C# 中查询 Web 服务,它 returns XML,我已将其解析为 XDocument。我删除了一个无关的节点,该节点 returns 关于服务调用的统计信息,剩下的是这样的:
<xml>
<element attr1="1" attr2="2" attr3="3" attr4="4" ... attrN="N" />
<element attr1="a" attr2="b" attr3="c" ... attrN="N" />
...
<element attr1="!" attr2="?" attr3=":" attr4="" ... attrN="N />
</xml>
我真的只对检索 attr2 和 attr3 感兴趣,所以我想删除所有其他属性以结束此操作:
<xml>
<element attr2="2" attr3="3" />
<element attr2="b" attr3="c" />
...
<element attr2="?" attr3=":" />
</xml>
但是,这是我正在使用的相关代码,它只删除了 attr1:
String[] WS_LookupFields = "attr2,attr3".Split(',');
var output = XDocument.Parse(WS_Output_Raw);
output.Descendants("system").Remove(); //removes query statistics
foreach (XAttribute attribute in output.Descendants("element").Attributes())
{
if (!Array.Exists<String>(WS_LookupFields, fieldname => attribute.Name == fieldname)) attribute.Remove();
}
问题在于foreach 仅 returns attr1 而不是attr1 通过attrN。有什么建议吗?
我想你需要两个循环:
// Loop all descendants
foreach (var element in output.Descendants("element"))
{
// for that element, loop all attributes
foreach (var attribute in element.Attributes())
{
if (!Array.Exists<String>(WS_LookupFields, fieldname => attribute.Name ==
fieldname)) attribute.Remove();
}
}
只需创建具有所需属性的新文档
var required = new HashSet<string> { "attr2", "attr3" };
var elements = original.Descendants("element").Select(element =>
{
var attributes = element.Attributes().Where(a => required.Contains(a.Name.LocalName));
return new XElement(element.Name, attributes);
});
var root = new XElement(original.Root.Name, elements);
var newDocument = new XDocument(original.Declaration, root);
使用这个:
var WS_LookupFields = "attr2,attr3".Split(',').ToList();
var output = XDocument.Parse(WS_Output_Raw);
foreach (var loElement in output.Descendants("element"))
{
//loElement.Attributes()
// .Where(item => !WS_LookupFields.Any(name => item.Name == name))
// .ToList()
// .ForEach(item => item.Remove());
//UPDATE: Charles Mager
loElement.Attributes()
.Where(item => !WS_LookupFields.Any(name => item.Name == name))
.Remove();
}
或者:
foreach (var loAttribute in output.Descendants("element").Attributes().ToList())
{
if (!WS_LookupFields.Contains(loAttribute.Name.ToString()))
loAttribute.Remove();
}
只需将 ToArray() 方法添加到您的 foreach 循环中:
foreach (XAttribute attribute in output.Descendants("element").Attributes().ToArray())
{
if (!Array.Exists<String>(WS_LookupFields, fieldname => attribute.Name == fieldname)) attribute.Remove();
}
有一些方法旨在从树中删除 xml 内容。您已经将一个用于 Element
s,将另一个用于属性。
建立查询以select您要删除的属性,然后删除它们。
var attrs = new HashSet<string>("attr2,attr3".Split(','));
foreach (var e in output.Descendants("element"))
e.Attributes().Where(a => !attrs.Contains(a.Name.LocalName)).Remove();
// or simply
output.Descendants("element")
.Attributes()
.Where(a => !attrs.Contains(a.Name.LocalName))
.Remove();