bash脚本向url发送请求并重写结果url

时间:2015-04-05 21:23:28

标签: bash curl sed grep

我正在尝试编写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

1 个答案:

答案 0 :(得分:0)

那么,XSLT就救了。请注意,XSLT会给你带来眼部癌症 - 语法很糟糕,但它是针对这类东西制作的。在任何情况下,结果都比使用awk或sed处理XML的任何尝试都要强大得多。

我们将编写一些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>&#xa;    </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>&#xa;    </xsl:text>
    </xsl:if>
  </xsl:template>

最后,这个为Url节点生成替换内容。它递归调用paramCount次,然后生成一个新的Url节点,其中包含我们从原始节点,当前计数器和.zip获取的url存根文本。它还添加了一个换行符(&#xa;内容),这对于保持XML有效并使其更易于阅读,并不是绝对必要的。

这可以在XSLT 2.0(它具有更强大的循环结构)中更简单地完成,但是没有任何东西支持XSLT 2.0,所以我们仍然坚持旧的方式。