我想删除特定标记的出现,使内部XML保持不变。我想通过一次通过(而不是搜索,替换,再次从头开始)这样做。例如,来自消息来源:
<element>
<RemovalTarget Attribute="Something">
Content Here
</RemovalTarget>
</element>
<element>
More Here
</element>
我希望结果如下:
<element>
Content Here
</element>
<element>
More Here
</element>
我尝试过这样的事情(原谅我,我是Linq的新手):
var elements = from element in doc.Descendants()
where element.Name.LocalName == "RemovalTarget"
select element;
foreach (var element in elements) {
element.AddAfterSelf(element.Value);
element.Remove();
}
但是第二次通过循环我得到一个空引用,大概是因为通过更改它来使集合无效。在潜在的大型文档中删除这些标记的有效方法是什么?
答案 0 :(得分:3)
您是否考虑过使用XSLT?看起来像是完美的源,因为您正在完成XSLT的用途,将一个XML文档转换为另一个XML文档。模板系统将毫无问题地为您钻研嵌套的肮脏。
Here是一个基本示例
答案 1 :(得分:3)
你必须通过调用ToList来跳过延迟执行,这可能不会损害你在大型文档中的性能,因为你只需要迭代并替换比原始文件低得多的大O.搜索。正如@jacob_c指出的那样,我应该使用element.Nodes()来正确替换它,正如@Panos所指出的那样,我应该反转列表以便准确处理嵌套替换。
此外,使用XElement.ReplaceWith,比大文档中的当前方法快得多:
var elements = doc.Descendants("RemovalTarget").ToList().Reverse();
/* reverse on the IList<T> may be faster than Reverse on the IEnumerable<T>,
* needs benchmarking, but can't be any slower
*/
foreach (var element in elements) {
element.ReplaceWith(element.Nodes());
}
最后一点,在回顾这可能用于什么时,我倾向于同意@Trull XSLT可能正是你真正想要的,如果说你要删除所有说&lt; b&gt;来自文档的标签。否则,享受这个相当不错且表现相当不错的LINQ to XML实现。
答案 2 :(得分:0)
我建议将XSLT作为Trull推荐作为最佳解决方案。
或者您可以查看使用字符串构建器和正则表达式匹配来删除项目。
您可以查看遍历文档,并使用节点和父节点来有效地将代码从节点内部移动到父节点,但这将是乏味的,并且对于其他可能的解决方案非常不必要
答案 3 :(得分:0)
轻量级解决方案是使用XmlReader通过输入文档和XmlWriter来编写输出。
注意:XmlReader和XmlWriter是抽象的,使用适合你的情境派生类。
答案 4 :(得分:0)
根据您管理XML的方式,您可以使用正则表达式删除标记。
这是一个简单的控制台应用程序,演示了如何使用正则表达式:
static void Main(string[] args)
{
string content = File.ReadAllText(args[0]);
Regex openTag = new Regex("<([/]?)RemovalTarget([^>]*)>", RegexOptions.Multiline);
string cleanContent = openTag.Replace(content, string.Empty);
File.WriteAllText(args[1], cleanContent);
}
这会在文件中留下换行符,但增加正则表达式应该不会太难。