我有一个很大的 XML 文件,其中包含许多如下元素:
<Foo Bar="Baz">
</Foo >
我希望他们都变成这样:
<Foo Bar="Baz" />
是否有一个工具可以自动帮我完成这个任务?
答案1
我无法xmlstarlet
按照您描述的方式获取收缩元素,除非您可以枚举要处理的元素名称。(这会替换元素值,因此您必须小心确保它已经为空。)
例子
# Create example source
p() { echo >&2; printf "%s\n%s\n" '<Foo Bar="Baz">' '</Foo >'; }
# Show initial output
p
<Foo Bar="Baz">
</Foo >
# Use xmlstarlet to edit the <Foo/> element
p | xmlstarlet edit --update '//Foo' --value ''
<?xml version="1.0"?>
<Foo Bar="Baz"/>
但是,如果你不介意使用sed
来处理你的 XML 文件(请注意,这通常是真是个坏主意)你也许可以使用类似这样的方法:
sed -Ez 's#<([[:alnum:]]*)( [^>]+)?>\r?\n[[:space:]]*</\1[[:space:]]*>#<\1\2 />#g'
它的工作过程如下。首先,它寻找第一对字符之间的模式#
,([[:alnum:]]*)( [^>]+)?>\r?\n[[:space:]]*</\1[[:space:]]*>
( ... )
- 分组表达式,每个表达式引用为\1
、\2
等。[[:alnum:]_]*
- 零个或多个字母数字或下划线字符[^>]+?
- 一个空格,后跟除 之外的任意内容>
,所有这些都是可选的>
- 文字>
字符\r?\n[[:space:]]*
- `可选 CR,后跟 NL,然后是零个或多个空格
如果找到则将其替换为<\1\2 />
,其中\1
和\2
是第一个和第二个括号表达式。
例子
p | sed -Ez 's#<([[:alnum:]]*)( [^>]+)?>\r?\n[[:space:]]*</\1[[:space:]]*>#<\1\2 />#g'
<Foo Bar="Baz" />