过滤掉 xml 树中带有空标签的节点,并且某些元素有时会换行

过滤掉 xml 树中带有空标签的节点,并且某些元素有时会换行

如何仅获取没有空的节点<有时为空标签>

只取一小段 xml 来进行尝试,要删除的是第一个为空的节点<sometimes_empty_tag></sometimes_empty_tag>

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<xml>
    <node>
        <sometimes_empty_tag></sometimes_empty_tag>
        <some_other_tag>xyz</some_other_tag>
    </node>
    <node>
        <sometimes_empty_tag>abc</sometimes_empty_tag>
        <some_other_tag>xyz</some_other_tag>
    </node>
    <node>
        <sometimes_empty_tag>abc</sometimes_empty_tag>
        <some_other_tag>mno
# some line wrap1
! some line wrap2
/ some line wrap3
        </some_other_tag>
    </node>
</xml>

应该变成没有第一个节点的 xml,因为第一个节点是空的<sometimes_empty_tag>

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<xml>
    <node>
        <sometimes_empty_tag>abc</sometimes_empty_tag>
        <some_other_tag>xyz</some_other_tag>
    </node>
    <node>
        <sometimes_empty_tag>abc</sometimes_empty_tag>
        <some_other_tag>mno
# some line wrap1
! some line wrap2
/ some line wrap3
        </some_other_tag>
    </node>
</xml>

没有换行,你可以只 grep 所有填充的标签并:

  • 下面 2 行 (= -A2) 和
  • 上面 1 行 (= -B1)

获取每个节点(然后去掉 grep 的“--”):

$ grep -E -A2 -B1 "<sometimes_empty_tag>.+</sometimes_empty_tag>" myfile.xml|grep -v -- "^--$" >> myfile_no_empty_sometimesemptytags.xml

然而,有些元素可能会换行,而且您不知道在哪里、何时以及有多少次换行。因此,您不能只取填充标签前的前 x 行和填充标签后的 y 行来完成。

如何过滤掉 xml 树中带有空标签且某些元素有变化的换行符的节点?

答案1

不!?

不要在 XML 上使用正则表达式,请参阅注释,其中提示RegEx 匹配除 XHTML 自包含标签之外的开放标签答案表明这个问题是网络上的一个老笑话。

您无法使用正则表达式解析 [X]HTML。因为 HTML 无法通过正则表达式解析。正则表达式不是可用于正确解析 HTML 的工具。[...以下是长答案,或者说这不是答案,而是一种艺术]

然而,这个问题只与标签有关,与价值观无关,即使你不应该,你仍然使用 RegEx 来实现。这允许接下来的两章。

快速搜索 Linux 终端的解析器:使用 XMLStarlet 在 Linux 终端中解析 XML。谁想在工作中展示这一点,就写一个答案吧。我不会花时间,因为上一章的解决方法对我来说已经足够了。

针对未改变的 XML 的 RegEx 修复(有效,但 RegEx 工作量相当大)

您可以使用一些正向和负向前瞻、非捕获组以及向允许字符的篮子中添加换行符来修复此问题。我至少可以找到</node>带有 的节点后面的结束标记<sometimes_empty_tag></sometimes_empty_tag>,这已经是一个相当长的 RegEx 表达式了。然而,我停止了这项工作,找到了一个简单的解决方法,如下所示。

RegEx 在 grep 之前更改 XML(有效且简单)

有一个简单的解决方法。借助sed -E(请参阅如何使用 sed 替换正则表达式捕获组?有关如何避免这种情况的更多信息),请替换:

^(\S.*)[\r|\n|\r\n]

和:

\1linewrapplaceholder

然后,如果换行符位于未缩进且不以空格开头的文本之后,则会用“linewrapplaceholder”替换换行符。这种替换也会发生在 xml 框架的开头和结尾,但这并没有什么坏处。

按照问题中的操作,删除所有具有空的节点sometimes_empty_tag通过以下方式:

$ grep -E -A2 -B1 "<sometimes_empty_tag>.+</sometimes_empty_tag>" myfile.xml|grep -v -- "^--$" >> myfile_no_empty_sometimesemptytags.xml

在新文件中myfile_no_empty_sometimesemptytags.xml,用换行替换回占位符,即替换:

linewrapplaceholder

和:

\r

您无需 XML 解析器,只需使用sed和即可完成grep

再次强调,最好避免在 XML 上使用 RegEx。还是去做吧。也许你的服务器不允许您安装解析器,而你又不想到处复制大文件?或者你只想在万般无奈的情况下快速解决问题?

相关内容