从XML中删除标记出现

时间:2008-11-03 20:41:28

标签: c# .net xml linq

我想删除特定标记的出现,使内部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();
}

但是第二次通过循环我得到一个空引用,大概是因为通过更改它来使集合无效。在潜在的大型文档中删除这些标记的有效方法是什么?

5 个答案:

答案 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);
    }

这会在文件中留下换行符,但增加正则表达式应该不会太难。