xmlstarlet 通过属性而不是元素匹配/解析
Posted
技术标签:
【中文标题】xmlstarlet 通过属性而不是元素匹配/解析【英文标题】:xmlstarlet match/parsing by attribute instead of element 【发布时间】:2021-12-28 02:54:43 【问题描述】:我有一个复杂的结构化 XML 文件,我尝试使用 xmlstartlet 从中解析一些值。我认为问题在于逻辑对象是由元素属性而不是实际元素名称来标识的。
为这个例子简化的文件 test.xml 看起来像这样:
<?xml version="1.0" encoding="utf-8"?>
<configDump>
<cluster top-level-assembly="XYZ12312312312">
</cluster>
<views>
<view status="ok" name="ABC">
<viewInitiators>
<viewInitiator id="ABCi1"></viewInitiator>
<viewInitiator id="ABCi2"></viewInitiator>
</viewInitiators>
<viewPorts>
<viewPort id="ABCp1"></viewPort>
<viewPort id="ABCp2"></viewPort>
</viewPorts>
<viewVolumes>
<viewVolume lun="1" id="ABCv1"></viewVolume>
<viewVolume lun="2" id="ABCv2"></viewVolume>
</viewVolumes>
</view>
<view status="ok" name="DEF">
<viewInitiators>
<viewInitiator id="DEFi1"></viewInitiator>
<viewInitiator id="DEFi2"></viewInitiator>
</viewInitiators>
<viewPorts>
<viewPort id="DEFp1"></viewPort>
<viewPort id="DEFp2"></viewPort>
</viewPorts>
<viewVolumes>
<viewVolume lun="1" id="DEFv1"></viewVolume>
<viewVolume lun="2" id="DEFv2"></viewVolume>
</viewVolumes>
</view>
</views>
</configDump>
我正在尝试使用如下所示的字段生成输出:
<top-level-assembly>-<view-name>,<viewInitiator-ID>
当我运行以下命令时:
xmlstarlet sel -t \
-m //cluster \
--var sn=@top-level-assembly \
-m //views/view \
--var view=@name \
-m //views/view/viewInitiators/viewInitiator \
-v 'concat($sn,"-",$view,",",@id)' -n test.xml
我得到以下输出:
XYZ12312312312-ABC,ABCi1
XYZ12312312312-ABC,ABCi2
XYZ12312312312-ABC,DEFi1
XYZ12312312312-ABC,DEFi2
XYZ12312312312-DEF,ABCi1
XYZ12312312312-DEF,ABCi2
XYZ12312312312-DEF,DEFi1
XYZ12312312312-DEF,DEFi2
如您所见,我在每个“视图”下获取了所有“启动器”值,而不仅仅是 XML 中该结构中的值。我期待并希望得到:
XYZ12312312312-ABC,ABCi1
XYZ12312312312-ABC,ABCi2
XYZ12312312312-DEF,DEFi1
XYZ12312312312-DEF,DEFi2
对我做错了什么有什么想法吗?
【问题讨论】:
【参考方案1】:对我做错了什么有什么想法吗?
-m
选项嵌套 - 到 xsl:for-each
语句 - 所以你要求每个 view
的所有 viewInitiator/@id
s。要查看生成的 XSLT 代码,请在 -t
之前添加一个 -C
选项。
可以通过以下方式生成所需的输出:
xmlstarlet sel -t \
--var sn='configDump/cluster/@top-level-assembly' \
-m '//viewInitiator' \
-v 'concat($sn,"-",../../@name,",",@id)' -n \
< file.xml
【讨论】:
谢谢!它实际上是最后一行中的“../../@name”,但我明白了要点!我是一个 XML 新手,xmlstarlet 文档不是很好(我认为它假设你有一些知识,但如果你不知道,我不会告诉你从哪里得到它),所以我很感激帮助。跨度> @Noso Opforu:您不是第一个对xmlstarlet 文档感到头疼的人。感谢您对丢失的../
的提醒;现在已经修好了。以上是关于xmlstarlet 通过属性而不是元素匹配/解析的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 xmlstarlet 为 xml 文件的每个节点添加不同的属性