我正在尝试编写bash脚本,我可以向网站发送请求并在Url中重写结果,首先是结果
<id>510</id>
<Title> bla bla </Title>
<Desc />
<ImagePath>http://www.example.com/images/510.jpg</ImagePath>
<Url>http://www.example.com/510_</Url>
<rtl>false</rtl>
<partCount>4</partCount>
在上面的结果中我想改变网址的结尾并期望它是
<Url>http://www.example.com/510_1.zip</Url>
<Url>http://www.example.com/510_2.zip</Url>
<Url>http://www.example.com/510_3.zip</Url>
<Url>http://www.example.com/510_4.zip</Url>
基于
<partCount>4</partCount>
所以
<partCount>
将具有不同的编号,并且基于此将更改Url路径 这是我的剧本
for ID in {44..4444};
do
MC=$(cat <<EOM
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
<id>$ID</id>
</OrM>
</soap:Body>
</soap:Envelope>
EOM
)
for num in {1..4}; do
res=$(curl -sL -d "$MC" "http://www.example.com/ne/eService.asmx" | xmllint --format - |
egrep -v 'Desc|rtl' | sed -e "s/_/_$num.zip/g" > tmp.tmp)
cat tmp.tmp
答案 0 :(得分:0)
我们将编写一些XSLT代码(我稍后会介绍它),将其放在文件urlexplode.xsl
中,然后我们可以在阳光下使用几乎所有的XSLT处理器应用转型。例如,使用xalan
:
curl -sL -d "$MC" "http://www.example.com/ne/eService.asmx" | xalan -xsl urlexplode.xsl
代码是
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Url">
<xsl:call-template name="urlexplode">
<xsl:with-param name="count" select="ancestor::*/partCount"/>
<xsl:with-param name="urlstub" select="text()"/>
</xsl:call-template>
</xsl:template>
<xsl:template name="urlexplode">
<xsl:param name="count" />
<xsl:param name="urlstub"/>
<xsl:if test="$count > 0">
<xsl:call-template name="urlexplode">
<xsl:with-param name="count" select="$count - 1"/>
<xsl:with-param name="urlstub" select="$urlstub" />
</xsl:call-template>
<Url><xsl:value-of select="$urlstub"/><xsl:value-of select="$count"/>.zip</Url>
<xsl:text>
 </xsl:text>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
丑陋,不是吗?幸运的是,恐怖是所有语法;它比看起来简单得多。让我们分一杯羹。我们有三个模板(在XSLT中可以像在其他语言中一样使用模板)。第一个是
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
这是一个身份模板;本质上是一个全能的处理程序,它可以逐字复制所有与另一个模板不匹配的内容,并在进行时递归地应用模板。它使XML保持在我们不想改变的那些地方。
<xsl:template match="Url">
<xsl:call-template name="urlexplode">
<xsl:with-param name="count" select="ancestor::*/partCount"/>
<xsl:with-param name="urlstub" select="text()"/>
</xsl:call-template>
</xsl:template>
适用于Url
代码。我们不是逐字复制那些,而是从祖先节点和partCount
标签内的文本中选择Url
,然后我们将整个事件传递给urlexplode
模板,做实际的工作。
<xsl:template name="urlexplode">
<xsl:param name="count" />
<xsl:param name="urlstub"/>
<xsl:if test="$count > 0">
<xsl:call-template name="urlexplode">
<xsl:with-param name="count" select="$count - 1"/>
<xsl:with-param name="urlstub" select="$urlstub" />
</xsl:call-template>
<Url><xsl:value-of select="$urlstub"/><xsl:value-of select="$count"/>.zip</Url>
<xsl:text>
 </xsl:text>
</xsl:if>
</xsl:template>
最后,这个为Url
节点生成替换内容。它递归调用paramCount
次,然后生成一个新的Url
节点,其中包含我们从原始节点,当前计数器和.zip
获取的url存根文本。它还添加了一个换行符(

内容),这对于保持XML有效并使其更易于阅读,并不是绝对必要的。
这可以在XSLT 2.0(它具有更强大的循环结构)中更简单地完成,但是没有任何东西支持XSLT 2.0,所以我们仍然坚持旧的方式。