XSLT 2.0:正则表达式提取和修改元素值

时间:2016-02-21 22:24:23

标签: regex xml xslt xpath

我有这个XML:

<xml>
   <row>
      <image><![CDATA[javascript: open_window_zoom('http://example.com/image.php?image=/images/test/example.png&pID=46391&download=noid_90.png&name=Test name', 975, 366);]]></image>
      <quantity>0</quantity>
   </row>
   <row>
      <image><![CDATA[javascript: open_window_zoom('http://example.com/image.php?image=/images/test/another.png&pID=06395&download=anotherfile.png&name=Test name', 975, 366);]]></image>
      <quantity>0</quantity>
   </row>
</xml>

可以从pID=NUMBERHERE&download=FILENAMEHERE.png元素中提取<image>(并在其前面添加新网址)吗?

输出应该是这样的:

<xml>
   <row>
      <image>http://newurl.com/pID=46391&download=noid_90.png</image>
      <quantity>0</quantity>
   </row>
   <row>
      <image>http://newurl.com/pID=06395&download=anotherfile.png</image>
      <quantity>0</quantity>
   </row>
</xml>

我尝试了一些东西,但我无法得到令人满意的结果。首先,我可以复制当前结构:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:template match="node()|@*">
     <xsl:copy>
       <xsl:apply-templates select="node()|@*"/>
     </xsl:copy>
 </xsl:template>

</xsl:stylesheet>

2 个答案:

答案 0 :(得分:2)

试试这个XSLT:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="@* | node()">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="image">
    <xsl:copy>
      <xsl:value-of select="concat('http://newurl.com/pID=', substring-before(substring-after(text(), '&amp;pID='), '&amp;name='))"/>
    </xsl:copy>
  </xsl:template>

</xsl:stylesheet>

答案 1 :(得分:2)

此XSLT 2.0样式表将值拆分为&,然后使用谓词仅过滤matches()提供的正则表达式,其中参数名称为pID或下载。使用@separator for xsl:value-of将值加入&

<xsl:stylesheet version="2.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output omit-xml-declaration="yes" indent="yes"/>
    <xsl:strip-space elements="*"/>

    <xsl:template match="node()|@*">
        <xsl:copy>
            <xsl:apply-templates select="node()|@*"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="image">
        <xsl:copy>
            <xsl:text>http://newurl.com/</xsl:text>
            <xsl:value-of select="tokenize(., '&amp;')[matches(., '(pID|download).*')]" 
                          separator="&amp;"/>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

或者,此XSLT 2.0样式表使用xsl:analyze-string来提取与提供的正则表达式匹配的文本:

<xsl:stylesheet version="2.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output omit-xml-declaration="yes" indent="yes"/>
    <xsl:strip-space elements="*"/>

    <xsl:template match="node()|@*">
        <xsl:copy>
            <xsl:apply-templates select="node()|@*"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="image">
        <xsl:copy>
            <xsl:text>http://newurl.com/</xsl:text>
            <xsl:analyze-string select="." regex=".*(pID=.*&amp;download=.*)&amp;.*">
                <xsl:matching-substring>
                    <xsl:value-of select="regex-group(1)"/>
                </xsl:matching-substring>
                <xsl:non-matching-substring></xsl:non-matching-substring>
            </xsl:analyze-string>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>