应用两个连续的xslt转换

时间:2013-06-17 11:40:15

标签: xslt

我有两个xslt转换应用于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()[not(self::*)]">
  <xsl:copy/>
 </xsl:template>

 <xsl:template match="*">
  <xsl:element name="{local-name()}">
   <xsl:apply-templates select="node()|@*"/>
  </xsl:element>
 </xsl:template>
</xsl:stylesheet>

第二个是从第一个输出中选择元素:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="/">
        <onSale><xsl:value-of select="//entry/content/product_product/sale_ok" /></onSale>
        <onlineOnly><xsl:value-of select="//entry/content/product_product/online" /></onlineOnly>
        <name><xsl:value-of select="//entry/content/product_product/name" /></name>
        <isbn><xsl:value-of select="//entry/content/product_product/isbn" /></isbn>
        <price><xsl:value-of select="//entry/content/product_product/price" /></price>
        <active><xsl:value-of select="//entry/content/product_product/active" /></active>
        <format><xsl:value-of select="//entry/content/product_product/format" /></format>
        <collection><xsl:value-of select="//entry/content/product_product/collection" /></collection>
        <dateParution><xsl:value-of select="//entry/content/product_product/date_parution"/></dateParution>
        <ean13><xsl:value-of select="//entry/content/product_product/ean13"/></ean13>
    </xsl:template>
</xsl:stylesheet>

如何在一个xslt转换中应用它们中的两个而不分别进行两次转换。 感谢

1 个答案:

答案 0 :(得分:0)

我不知道你的环境支持哪个版本的XSLT,你可以使用XSLT 2.0

<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:variable name="step1">
 <xsl:apply-templates mode="step1"/>
</xsl:variable>

 <xsl:template match="@*|node()[not(self::*)]" mode="step1">
  <xsl:copy/>
 </xsl:template>

 <xsl:template match="*" mode="step1">
  <xsl:element name="{local-name()}">
   <xsl:apply-templates select="node()|@*" mode="step1"/>
  </xsl:element>
 </xsl:template>

    <xsl:template match="/">
      <xsl:apply-templates select="$step1//entry"/>
    </xsl:template>

    <xsl:template match="entry">
        <onSale><xsl:value-of select="content/product_product/sale_ok" /></onSale>
        <onlineOnly><xsl:value-of select="content/product_product/online" /></onlineOnly>
        <name><xsl:value-of select="content/product_product/name" /></name>
        <isbn><xsl:value-of select="content/product_product/isbn" /></isbn>
        <price><xsl:value-of select="content/product_product/price" /></price>
        <active><xsl:value-of select="content/product_product/active" /></active>
        <format><xsl:value-of select="content/product_product/format" /></format>
        <collection><xsl:value-of select="content/product_product/collection" /></collection>
        <dateParution><xsl:value-of select="content/product_product/date_parution"/></dateParution>
        <ean13><xsl:value-of select="content/product_product/ean13"/></ean13>
    </xsl:template>

</xsl:stylesheet>

我会进一步重构并编写像

这样的模板
<xsl:template match="sale_ok">
  <onSale>
    <xsl:value-of select="."/>
  </onSale>
</xsl:template>

如果你使用XSLT 1.0,你需要一个扩展函数来处理变量的内容,使用apply-templates这样做

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

<xsl:variable name="step1">
 <xsl:apply-templates mode="step1"/>
</xsl:variable>

 <xsl:template match="@*|node()[not(self::*)]" mode="step1">
  <xsl:copy/>
 </xsl:template>

 <xsl:template match="*" mode="step1">
  <xsl:element name="{local-name()}">
   <xsl:apply-templates select="node()|@*" mode="step1"/>
  </xsl:element>
 </xsl:template>

    <xsl:template match="/">
      <xsl:apply-templates select="exsl:node-set($step1)//entry"/>
    </xsl:template>

    <xsl:template match="entry">
        <onSale><xsl:value-of select="content/product_product/sale_ok" /></onSale>
        <onlineOnly><xsl:value-of select="content/product_product/online" /></onlineOnly>
        <name><xsl:value-of select="content/product_product/name" /></name>
        <isbn><xsl:value-of select="content/product_product/isbn" /></isbn>
        <price><xsl:value-of select="content/product_product/price" /></price>
        <active><xsl:value-of select="content/product_product/active" /></active>
        <format><xsl:value-of select="content/product_product/format" /></format>
        <collection><xsl:value-of select="content/product_product/collection" /></collection>
        <dateParution><xsl:value-of select="content/product_product/date_parution"/></dateParution>
        <ean13><xsl:value-of select="content/product_product/ean13"/></ean13>
    </xsl:template>

</xsl:stylesheet>

另一方面,我想知道为什么我们最近在尝试消除命名空间或忽略它们时遇到很多问题,如果你真的想用XSLT 2.0那么做呢

<xsl:template match="*:sale_ok">
  <onSale>
     <xsl:value-of select="."/>
  <onSale>
</xsl:template>

等等就足够了。