使用grep、awk或sed等shell工具解析xml文件。
xmlstarlet是一个命令行XML工具包,可以将复杂的XSLT模板表达为一系列短命令行开关。以上内容展示了如何使用类似grep、awk或sed等shell工具解析xml文件。这里给出了一个例子,假设我们有一个格式良好的XML文档repos.xml,通过以下命令行将其通过XMLStarlet过滤器运行:
$ cat repos.xml | xmlstarlet sel -t -m '//repositories-item' \ -i 'type="hosted"' -v 'name' -n
这将输出一行结果:
hosted-npm
下面我们来看一下XMLStarlet的命令行:
- 我们使用
sel
开关指定了选择模式的命令。 - 我们使用
-t
开关指定了选择模板。 - 我们使用
-m
开关将解析器限制为<repositories-item>
元素。 - 我们使用
-i
开关选择具有"type"元素值为"hosted"的元素。 - 我们使用
-v
开关打印出"name"元素的值。 - 我们使用
-n
开关在每行输出之后打印一个换行符。
这是XMLStarlet生成的等价XSLT代码:
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:exslt="http://exslt.org/common" version="1.0" extension-element-prefixes="exslt">
<xsl:output omit-xml-declaration="yes" indent="no"/>
<xsl:template match="/">
<xsl:for-each select="//repositories-item">
<xsl:choose>
<xsl:when test="type="hosted"">
<xsl:call-template name="value-of-template">
<xsl:with-param name="select" select="name"/>
</xsl:call-template>
<xsl:value-of select="' '"/>
</xsl:when>
</xsl:choose>
</xsl:for-each>
</xsl:template>
<xsl:template name="value-of-template">
<xsl:param name="select"/>
<xsl:value-of select="$select"/>
<xsl:for-each select="exslt:node-set($select)[position()>1]">
<xsl:value-of select="' '"/>
<xsl:value-of select="."/>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
根据Charles Duffy的建议,可以使用XMLStarlet的-C
选项生成此XSLT规范:
xmlstarlet sel -C -t -m '//repositories-item' \ -i 'type="hosted"' -v 'name' -n > hosted-repos.xslt
生成的XSLT规范可以直接与xsltproc
一起使用:
cat repos.xml | xsltproc hosted-repos.xslt -
可以向OP展示如何使用xsltproc
应用这个XSLT,以确保他们了解在没有安装XMLStarlet的服务器上也可以使用这个解决方案。
使用Shell工具(如grep、awk或sed)解析xml的原因是缺乏专门的xml工具。在解决方法中,我们可以使用awk来处理这个问题,通过使用封闭标签来定义记录的分隔符。首先,我们可以使用以下命令来提取包含特定标签的内容:
$ awk -v RS='</?repositories-item>' '/<type>hosted<\/type>/' file
<name>hosted-npm</name>
<type>hosted</type>
请注意,这需要多字符的RS,而GNU awk支持这个功能。然后,我们可以使用以下命令来更好地控制匹配和输出内容:
$ awk -v RS='</?repositories-item>' -F'[<>]' '
{delete a;
for(i=2;i<=NF;i+=4) a[$i]=$(i+1);
if(a["type"]=="hosted") print a["name"] }' file
hosted-npm
通过以上方法,我们可以使用Shell工具来解析xml文件,提取所需的信息。