1

我想从我的 XML 结构中删除所有属性。我的选择是正则表达式,但如果有更简单的方法,我愿意接受建议。

为了挑选出一个修复标签,我使用了以下内容。

String clean = Regex.Replace(filled, ".*?<holder[^>]*?>(.*?)</holder>.*?", "$1");

这给了我标签持有人的内容。我现在想保留文本质量,但省略内部标签中的所有属性。我尝试了以下方法。

String plain1 = Regex.Replace(clean, "(<[^>]*?>)(.*?)(</[^>]*?>)", "$1$2$3");
String plain2 = Regex.Replace(clean, "(<[a-zA-Z]*?)([^>]*?)(>)", "$1$3");

但它给了我同样的东西(plain1)和没有原始名称的空标签(plain2)。什么都没有清理干净,或者一切都清理干净了。我做错了什么?

我注意到将开始更改为加号,给我的标签只包含名称的第一个字母,所以我很确定以下是正确的方法,只要我能以1 美元的价格制作拾取部分最大。我怎么做?

String plain3 = Regex.Replace(clean, "(<[a-zA-Z]+?)([^>]*?)(>)", "$1$3");
4

3 回答 3

2

您需要跳过第一个括号中的问号。

String plain3 = Regex.Replace(clean, "(<[a-zA-Z]+)([^>]*?)(>)", "$1$3");

一些观察。

  • 您需要处理结束标记。您现在正在跳过斜线字符。
Regex.Replace(clean, "(<[/a-zA-Z]+)([^>]*?)(>)", "$1$3");
  • 你不需要$2。不是真的3 美元,也不是。
Regex.Replace(clean, "(<[a-zA-Z]+)[^>]*?>", "$1>");
  • 在正则表达式中有更好的方法来表达“只有字母”。
Regex.Replace(clean, @"(<[\w]+)([^>]*?)(>)", "$1$3");

所以最后,你可能会得到以下结果。

Regex.Replace(clean, @"(<[/\w]*)[^>]*?>", "$1>");
于 2013-03-23T22:46:29.187 回答
2

我的选择是正则表达式,但如果有更简单的方法,我愿意接受建议。

我想你已经知道不要试图用 regex 解析 xml/html,使用真正的 xml 解析器来处理 xmls

我会用Linq To XML. 借助递归函数可以轻松完成

var xDoc = XDocument.Load(fileName1);
RemoveAttributes(xDoc.Root);
xDoc.Save(fileName2);

void RemoveAttributes(XElement xRoot)
{
    foreach (var xAttr in xRoot.Attributes().ToList())
        xAttr.Remove();

    foreach (var xElem in xRoot.Descendants())
        RemoveAttributes(xElem);
}
于 2013-03-31T16:16:06.320 回答
1

请不要为此使用正则表达式。

以下是如何使用纯 XML 实现它的示例(前半部分只是控制台的东西,您需要的方法是 ProcessNode):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using System.Xml.XPath;

internal static class Program
{
    public static void Main(string[] args)
    {
        var xmlFile = XElement.Load(@"c:\file.xml"); // Use your file here
        var blockquote = xmlFile.XPathSelectElement("/");

        var doc = new XDocument();
        doc.Add(new XElement("root"));
        var processedNodes = ProcessNode(blockquote);
        foreach (var node in processedNodes)
        {
            doc.Root.Add(node);
        }

        var sb = new StringBuilder();
        var settings = new XmlWriterSettings();
        settings.OmitXmlDeclaration = true;
        settings.Encoding = Encoding.UTF8;
        settings.Indent = true;
        using (var sw = XmlWriter.Create(sb, settings))
        {
            doc.WriteTo(sw);
        }

        Console.OutputEncoding = Encoding.UTF8;
        Console.WriteLine(sb);
    }

    private static IEnumerable<XNode> ProcessNode(XElement parent)
    {
        foreach (var node in parent.Nodes())
        {
            if (node is XText)
            {
                yield return node;
            }
            else if (node is XElement)
            {
                var container = (XElement)node;
                var copy = new XElement(container.Name.LocalName);
                var children = ProcessNode(container);
                foreach (var child in children)
                {
                    copy.Add(child);
                }
                yield return copy;
            }
        }
    }
}
于 2013-03-23T23:18:41.563 回答