XSLT param identity transform without input XML

ぐ巨炮叔叔 提交于 2019-12-06 05:51:06

Make the following changes to get your XSLT 2.0 transformation to work:

  1. Add as="node()" to the xsl:param.
  2. Match the root element of the (ignored) input XML and <xsl:apply-templates select="$products"/> from there to get started on the param XML.
  3. Remove $products from the xs:apply-templates of your other templates.
  4. Remove name="initial" from your identity template.

Then, your XSLT 2.0 transformation with the above updates:

<?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>

Will produce the desired output 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 Solution

OP's transformation was declared to use XSLT 2.0, but for anyone coming later wanting to do this in XSLT 1.0, it is possible via 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>
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!