XmlStarlet

XmlStarlet是一个xml处理工具。它可按xpath对xml获取元素或者修改元素。
不带参数运行xmlstarlet,就会输出xmlstarlet的功能列表。下面是截取的一部份。

XMLStarlet Toolkit: Command line utilities for XML
Usage: xmlstarlet [] []
where is one of:
ed (or edit) - Edit/Update XML document(s)
sel (or select) - Select data or query XML document(s) (XPATH, etc)
el (or elements) - Display element structure of XML document

其中sel和ed分别是选择和编辑命令,el用于大概浏览xml文档的结构。

浏览xml的结构

以这个pom.xml为例。
xmlstarlet el pom.xml会显示pom.xml的所有节点,结果里的每一行都对应着一条xpath。相同xpath的所有节点都会输出一遍,要想去重,可以使用xmlstarlet el -u pom.xml
如果还要显示属性的话,使用-a,比如xmlstarlet el -a pom.xml,输出结果中包含下面几行:

project
project/@xmlns
project/@xmlns:xsi
project/@xsi:schemaLocation
project/modelVersion
project/groupId
project/artifactId

其中@开头的xmlns、xmlns:xsi、xsi:schemaLocation是project节点的三个属性,分成了三行显示。

如果要显示属性的值,使用-v,比如xmlstarlet el -v pom.xml,输出结果中包含下面几行:

project[@xmlns=’http://maven.apache.org/POM/4.0.0‘ and @xmlns:xsi=’http://www.w3.org/2001/XMLSchema-instance‘ and @xsi:schemaLocation=’http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd‘]
project/modelVersion
project/groupId

其中project的三个属性xmlns、xmlns:xsi、xsi:schemaLocation显示在了一行。

使用xpath选择节点

先介绍简单的没有命名空间的情况,将pom.xml里的xmlns和xsi:schemaLocation属性都删掉,保存成pom2.xml(linux中可使用sed -e 's/ xmlns.*=".*"//g' pom.xml | sed 's/xsi:schemaLocation=".*"//g' > pom2.xml)。
xmlstarlet sel命令是对xml进行输出的命令。

  1. 查询pom2.xml里子节点artifactId为leveldb的dependency节点的version节点的文本:
    xmlstarlet sel -t -v "//dependency[artifactId='leveldb']/version" -n pom2.xml
    这会输出0.7
    -t 一般sel命令必须至少有一个-t选项,它指定新的template,代表一项操作。template是xslt中的内容。
    -v 是指把xpath取出值打印出来
    -n 是指打印一个换行符,可以试试不加-n的效果。
  2. 打印pom2.xml里所有dependency节点的artifact节点和version节点的文本:
    打印artifact节点可以用-v '//dependency/artifactId',打印version节点可以用-v '//dependency/version' ,但是输出是先输出所有的artifactId,再输出所有的version。想要每行输出一组的artifactId和version,可以借助-m选项。
    xmlstarlet sel -t -m "//dependency" -v "artifactId" -o " " -v "version" -n pom2.xml
    -m 按xpath对xml进行匹配,对每个匹配到的节点,用-v输出值。这里是输出一个artifactId,接着输出一个version
    -o 是输出一个指定字符串,这里指定的是一个空格,用来隔开artifactId和version
    xpath还可以根据属性选择,或者选择属性,或者函数。关于xpath的内容可以去w3cschool看。

xslt

xmlstarlet使用了xslt来选择和输出xml。-t对应xsl:template-v对应xsl:value-of
xmlstarlet可以打印每个操作的相应的xslt,比如:
xmlstarlet sel -C -t -m "//dependency" -v "artifactId" -o " " -v "version" -n pom2.xml
这会输出:

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

 

<?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="//dependency">

<xsl:call-template name="value-of-template">

<xsl:with-param name="select" select="artifactId"/>

</xsl:call-template>

<xsl:text> </xsl:text>

<xsl:call-template name="value-of-template">

<xsl:with-param name="select" select="version"/>

</xsl:call-template>

<xsl:value-of select="'&#10;'"/>

</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()&gt;1]">

<xsl:value-of select="'&#10;'"/>

<xsl:value-of select="."/>

</xsl:for-each>

</xsl:template>

</xsl:stylesheet>

可以看到,-t对应xsl:template。 -m "//dependency"对应<xsl:for-each select="//dependency",它的下面包含了两个<xsl:call-template name="value-of-template">,各对应一个-v选项,这使每个dependency节点下的artifactId节点和version节点成对输出。而xmlstarlet sel -C -t -v "//dependency/artifactId" -o " " -v "//dependency/version" -n pom2.xml的输出(这里没执行)则显示是对整个文档先输出所有的”//dependency/artifactId”,再输出所有的version。

命名空间

前面提到pom2.xml是将pom.xml里的xmlns和xsi属性删除后的结果,上面的例子如果在pom.xml上执行都是没有结果的。这是因为xmlstarlet对xml的命名空间的识别的原因。pom.xml里的project节点声明了xmlns命名空间属性,要对它按xpath进行选择,要么把命名空间属性都删掉,像上面做的那样,要么在xpath里都指定命名空间。
xmlstarlet提供字符_代表默认命名空间。比如将上面的一行输出artifactId和version的例子改写为
xmlstarlet sel -t -m "//_:dependency" -v "_:artifactId" -o " " -v "_:version" -n pom.xml
这样就可以处理pom.xml了。
xmlstarlet还提供了-N选项为命名空间进行命名。比如pom.xml里有两个命名空间,xmlstarlet可以写成:
xmlstarlet sel -N d="http://maven.apache.org/POM/4.0.0" -N x="http://www.w3.org/2001/XMLSchema-instance" -t -m "//d:dependency" -v "d:artifactId" -o " " -v "d:version" -n pom.xml
这里d对应maven,x对应XMLSchema-instance。

编辑xml节点

xmlstarlet ed命令是对xml进行编辑的命令。本身很简单。
将dom4j的version从1.6.1与为1.7.1:
xmlstarlet ed -u "//dependency[artifactId='dom4j']/version" -v "1.7.1" pom2.xml

虽然复杂的逻辑最终还是需要靠写代码,但是xmlstarlet还是节省了大量工作量。

转载于:https://my.oschina.net/tick/blog/853464

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值