使用 xmlstarlet 将 xml 个节点提取为 table
extract xml nodes as table with xmlstarlet
我有一个非常简单但巨大的 xml(超过 50.000 行)。我只想提取一个重复节点作为 table(环)。考虑到这是一个例子。真正的文件在“ring”节点中有300多个元素,所以我尽量避免写逐个元素提取的命令。
举个小例子
<xml>
<root>
<ration>
<ring>
<id value="1"/>
<date value="2021-01-01"/>
<price value="435"/>
</ring>
</ration>
</root>
<root>
<ration>
<ring>
<id value="14"/>
<date value="2021-02-01"/>
<price value="745"/>
</ring>
</ration>
</root>
</xml>
我想实现的是:
这个 xmlstarlet 命令正在运行,我得到了正确的结果,但现在考虑执行 300 次(对于每个元素,我必须将调用插入到 concat 部分)。我需要一个更简单的方法。
xmlstarlet sel -T -t -m '//root/ration/ring' -v "concat(id/@value,',',date/@value,',',price/@value)" -n file.xml
id, date, price
1, 2021-01-01, 435
14, 2021-02-01, 745
好久没问了。尽管如此...
xmlstarlet sel -T \
-t -m '//root[1]/ration/ring/*[boolean(@value)]' \
-v 'substring(", ", 1, 2*(position() != 1))' -v 'local-name()' -b -nl \
-t -m '//root' -m 'ration/ring/*[boolean(@value)]' \
-v 'substring(", ", 1, 2*(position() != 1))' -v '@value' -b -nl \
file.xml
输出:
id, date, price
1, 2021-01-01, 435
14, 2021-02-01, 745
模板 #1 发出 header,#2 数据。 -m
表达式 #1 和 #3 匹配具有 @value
属性的 ring
的 child 个元素。一起使用 -m
和 -b
就可以了。如果 @value
替换为 @*
所有属性都被选中;使用诸如 @*[name()="value" or name()="otherval"]
的谓词,选择可以是 fine-tuned.
值的分离在 XSLT 1.0 中比在 2.0 中需要更多的工作:在这种情况下,substring
函数调用 returns 第一个值的空字符串,其中 position() != 1
为假(转换为数字 0),以及 2 个字符的字符串(逗号和 space)用于以下为真 (1).
顺便说一下,任何 lower/upper 组合中以 xml
开头的标签/PI 名称是 reserved.
我有一个非常简单但巨大的 xml(超过 50.000 行)。我只想提取一个重复节点作为 table(环)。考虑到这是一个例子。真正的文件在“ring”节点中有300多个元素,所以我尽量避免写逐个元素提取的命令。
举个小例子
<xml>
<root>
<ration>
<ring>
<id value="1"/>
<date value="2021-01-01"/>
<price value="435"/>
</ring>
</ration>
</root>
<root>
<ration>
<ring>
<id value="14"/>
<date value="2021-02-01"/>
<price value="745"/>
</ring>
</ration>
</root>
</xml>
我想实现的是: 这个 xmlstarlet 命令正在运行,我得到了正确的结果,但现在考虑执行 300 次(对于每个元素,我必须将调用插入到 concat 部分)。我需要一个更简单的方法。
xmlstarlet sel -T -t -m '//root/ration/ring' -v "concat(id/@value,',',date/@value,',',price/@value)" -n file.xml
id, date, price
1, 2021-01-01, 435
14, 2021-02-01, 745
好久没问了。尽管如此...
xmlstarlet sel -T \
-t -m '//root[1]/ration/ring/*[boolean(@value)]' \
-v 'substring(", ", 1, 2*(position() != 1))' -v 'local-name()' -b -nl \
-t -m '//root' -m 'ration/ring/*[boolean(@value)]' \
-v 'substring(", ", 1, 2*(position() != 1))' -v '@value' -b -nl \
file.xml
输出:
id, date, price
1, 2021-01-01, 435
14, 2021-02-01, 745
模板 #1 发出 header,#2 数据。 -m
表达式 #1 和 #3 匹配具有 @value
属性的 ring
的 child 个元素。一起使用 -m
和 -b
就可以了。如果 @value
替换为 @*
所有属性都被选中;使用诸如 @*[name()="value" or name()="otherval"]
的谓词,选择可以是 fine-tuned.
值的分离在 XSLT 1.0 中比在 2.0 中需要更多的工作:在这种情况下,substring
函数调用 returns 第一个值的空字符串,其中 position() != 1
为假(转换为数字 0),以及 2 个字符的字符串(逗号和 space)用于以下为真 (1).
顺便说一下,任何 lower/upper 组合中以 xml
开头的标签/PI 名称是 reserved.