没有输入XML的XSLT参数标识转换

时间:2014-12-09 10:16:39

标签: xml xslt params

我正在尝试这几天但没有成功。我有以下XSLT,它不接受任何输入XML,但有一个参数作为XML:

<xsl:stylesheet version="2.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes" />
    <xsl:param name="products">
        <products author="Jesper">
            <product id="p1">
                <name>Delta</name>
                <price>800</price>
                <stock>4</stock>
                <country>Denmark</country>
            </product>
            <product id="p2">
                <name>Golf</name>
                <price>1000</price>
                <stock>5</stock>
                <country>Germany</country>
            </product>
            <product id="p3">
                <name>Alfa</name>
                <price>1200</price>
                <stock>19</stock>
                <country>Germany</country>
            </product>
            <product id="p4">
                <name>Foxtrot</name>
                <price>1500</price>
                <stock>5</stock>
                <country>Australia</country>
            </product>
            <!-- p5 is a brand new product -->
            <product id="p5">
                <name>Tango</name>
                <price>1225</price>
                <stock>3</stock>
                <country>Japan</country>
            </product>
        </products>
    </xsl:param>
    <xsl:template match="@*|node()" name="initial">
        <xsl:copy>
            <xsl:apply-templates select="$products / @*|node()" />
        </xsl:copy>
    </xsl:template>
    <xsl:template match="products">
        <xsl:copy>
            <xsl:attribute name="dateUpdated">
      <xsl:value-of select="current-dateTime()" />
    </xsl:attribute>
            <xsl:apply-templates select="$products / @*|node()" />
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

这是来自here的示例我刚刚使用输入XML作为参数。 我的问题是如何在XSLT参数上进行身份转换并使这种转换有效?

1 个答案:

答案 0 :(得分:2)

进行以下更改以使XSLT 2.0转换正常工作:

  1. as="node()"添加到xsl:param
  2. 匹配(忽略)输入XML的根元素 <xsl:apply-templates select="$products"/>从那里得到 从param XML开始。
  3. 从您对方的$products移除xs:apply-templates 模板。
  4. 从您的身份模板中删除name="initial"
  5. 然后,使用上述更新进行XSLT 2.0转换:

    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet version="2.0"
                    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
      <xsl:output method="xml" indent="yes" />
      <xsl:param name="products" as="node()">
        <products author="Jesper">
          <product id="p1">
            <name>Delta</name>
            <price>800</price>
            <stock>4</stock>
            <country>Denmark</country>
          </product>
          <product id="p2">
            <name>Golf</name>
            <price>1000</price>
            <stock>5</stock>
            <country>Germany</country>
          </product>
          <product id="p3">
            <name>Alfa</name>
            <price>1200</price>
            <stock>19</stock>
            <country>Germany</country>
          </product>
          <product id="p4">
            <name>Foxtrot</name>
            <price>1500</price>
            <stock>5</stock>
            <country>Australia</country>
          </product>
          <!-- p5 is a brand new product -->
          <product id="p5">
            <name>Tango</name>
            <price>1225</price>
            <stock>3</stock>
            <country>Japan</country>
          </product>
        </products>
      </xsl:param>
      <xsl:template match="@*|node()">
        <xsl:copy>
          <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
      </xsl:template>
      <xsl:template match="products">
        <xsl:copy>
          <xsl:attribute name="dateUpdated">
            <xsl:value-of select="current-dateTime()" />
          </xsl:attribute>
          <xsl:apply-templates select="@*|node()" />
        </xsl:copy>
      </xsl:template>
      <xsl:template match="/">
        <xsl:apply-templates select="$products"/>
      </xsl:template>
    </xsl:stylesheet>
    

    将生成所需的输出XML:

    <?xml version="1.0" encoding="UTF-8"?>
    <products dateUpdated="2014-12-09T06:38:15.8-05:00" author="Jesper">
       <product id="p1">
          <name>Delta</name>
          <price>800</price>
          <stock>4</stock>
          <country>Denmark</country>
       </product>
       <product id="p2">
          <name>Golf</name>
          <price>1000</price>
          <stock>5</stock>
          <country>Germany</country>
       </product>
       <product id="p3">
          <name>Alfa</name>
          <price>1200</price>
          <stock>19</stock>
          <country>Germany</country>
       </product>
       <product id="p4">
          <name>Foxtrot</name>
          <price>1500</price>
          <stock>5</stock>
          <country>Australia</country>
       </product>
       <product id="p5">
          <name>Tango</name>
          <price>1225</price>
          <stock>3</stock>
          <country>Japan</country>
       </product>
    </products>
    

    XSLT 1.0解决方案

    OP的变换被宣布为使用XSLT 2.0,但对于后来想要在XSLT 1.0中执行此操作的人来说,可以通过document('')

    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet version="1.0"
                    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
      <xsl:output method="xml" indent="yes" />
      <xsl:param name="products">
        <products author="Jesper">
          <product id="p1">
            <name>Delta</name>
            <price>800</price>
            <stock>4</stock>
            <country>Denmark</country>
          </product>
          <product id="p2">
            <name>Golf</name>
            <price>1000</price>
            <stock>5</stock>
            <country>Germany</country>
          </product>
          <product id="p3">
            <name>Alfa</name>
            <price>1200</price>
            <stock>19</stock>
            <country>Germany</country>
          </product>
          <product id="p4">
            <name>Foxtrot</name>
            <price>1500</price>
            <stock>5</stock>
            <country>Australia</country>
          </product>
          <!-- p5 is a brand new product -->
          <product id="p5">
            <name>Tango</name>
            <price>1225</price>
            <stock>3</stock>
            <country>Japan</country>
          </product>
        </products>
      </xsl:param>
      <xsl:template match="@*|node()">
        <xsl:copy>
          <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
      </xsl:template>
      <xsl:template match="products">
        <xsl:copy>
          <xsl:attribute name="dateUpdated">
            <xsl:value-of select="current-dateTime()" />
          </xsl:attribute>
          <xsl:apply-templates select="@*|node()" />
        </xsl:copy>
      </xsl:template>
      <xsl:template match="/">
        <xsl:apply-templates select="document('')//xsl:param[@name='products']/products"/>
      </xsl:template>
    </xsl:stylesheet>