使用与序列匹配两次的正则表达式从 xml 中删除空元素

本文关键字:正则表达式 两次 xml 元素 删除 | 更新日期: 2023-09-27 18:31:05

我希望从XML文件中删除空元素,因为读者需要一个值。它不是没有内容的 nil xsi:nil="true"或元素<Element />在 C# 中使用空元素反序列化 Xml。但是内部只是缺少的元素<Element></Element>

我尝试编写自己的代码来删除这些元素,但我的代码太慢,文件太大。每个项目的末尾也将包含此模式。因此,以下正则表达式将删除有效的 xml:
@"<.*></*>

我需要某种正则表达式来确保两个 * 的模式相同。

所以:

<Item><One>1</One><Two></Two><Three>3</Three></Item>

将更改为:

<Item><One>1</One><Three>3</Three></Item>

因此,它都是一行的事实使这变得更加困难,因为这意味着项目的结尾就在三的结尾之后,产生了我想寻找的模式。

我无法访问允许重新创建有效 xml 的原始数据。

使用与序列匹配两次的正则表达式从 xml 中删除空元素

您想在<中捕获一个或多个单词字符...
通过使用对第一组捕获的内容的反向引用'1 >并匹配结束标记。

<('w+)></'1>

在正则表达式101观看演示

AFAIK 没有必要捕获任何组,因为<a></b>(这将匹配一个简单的正则表达式而不捕获)只是无效的 XML,它不能在您的文件中(除非您正在解析 HTML,在这种情况下 - 即使可以完成 - 我建议不要使用正则表达式)。仅当您匹配非空节点时才需要捕获组,但事实并非如此。

请注意,您的正则表达式有问题(除了未转义的 /),因为您将任何字符. 匹配,但不允许在 XML 标记中包含任何字符。如果你绝对想使用.*那么它应该是.*?的,你应该排除/)。

我要做的是使正则表达式尽可能简单(仍然匹配有效的XML节点名称,或者 - 甚至更好 - 只知道您的数据输入):

<'w+><'/'w+>

您应该/可能更好地检查标签名称,例如's*['w'd]+'s*可能稍微好一点,步骤较少的正则表达式对于非常大的文件将表现得更好。此外,您可能希望在开始标记和结束标记之间添加一个可选的换行符。

请注意,您可能需要循环,直到不再进行替换,例如,如果您有<outer><inner></inner></outer>并且您希望将其简化为空字符串(特别是在这种情况下,不要忘记编译您的正则表达式)。

Use XML Linq

string xml = "<Item><One>1</One><Two></Two><Three>3</Three></Item>";
            XElement item = XElement.Parse(xml);
            item = new XElement("Item", item.Descendants().Where(x => x.Value.Length != 0));