【问题标题】:strip out tag occurrences from XML从 XML 中去除标签出现
【发布时间】:2008-11-03 20:41:28
【问题描述】:

我想去掉出现的特定标记,保持内部 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();
}

但是在第二次通过循环时,我得到了一个空引用,大概是因为通过更改集合使其无效。在可能很大的文档上删除这些标签的有效方法是什么?

【问题讨论】:

    标签: c# .net xml linq


    【解决方案1】:

    您必须通过调用 ToList 来跳过延迟执行,这可能不会损害您在大型文档中的性能,因为您将在比原来低得多的 big-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 可能是您真正想要的,如果说您要从文档中删除所有说 标记.否则,请享受这个相当不错且性能相当不错的 LINQ to XML 实现。

    【讨论】:

    • .如果 RemovalTarget 元素包含子元素,Value 将不起作用
    【解决方案2】:

    您是否考虑过使用 XSLT?似乎是完美的解决方案,因为您所做的正是 XSLT 的用途,将一个 XML 文档转换为另一个。模板系统将毫无问题地为您深入研究嵌套的讨厌。

    Here 是一个基本的例子

    【讨论】:

      【解决方案3】:

      我建议按照 Trull 推荐的最佳解决方案执行 XSLT。

      或者您可能会考虑使用字符串生成器和正则表达式匹配来删除项目。

      您可以查看文档,并使用节点和父节点有效地将代码从节点内部移动到父节点,但这会很乏味,而且对于其他潜在的解决方案来说非常不必要.

      【讨论】:

        【解决方案4】:

        一个轻量级的解决方案是使用 XmlReader 来处理输入文档并使用 XmlWriter 来写入输出。

        注意:XmlReader 和 XmlWriter 类是抽象的,请使用适合您情况的派生类。

        【讨论】:

          【解决方案5】:

          根据您管理 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);
              }
          

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

          【讨论】:

          • 如果您可以控制源 XML,则将 XML 处理为字符串数据非常简单,如果您不控制,则会充满无数复杂性。野外的 XML 包含 CDATA 和 cmets,它们引入了许多特殊情况,通常最好坚持使用基于 DOM 的方法。
          猜你喜欢
          • 2012-10-01
          • 2013-03-24
          • 2013-08-01
          • 2013-09-03
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-07-13
          • 2014-03-19
          相关资源
          最近更新 更多