I'm trying this for days and no success. I have following XSLT which doesn't take any input XML, but has one param as 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>
This is example from here I just used input XML as param. My question is how to do identity transform on XSLT param and make this transformation work?
Make the following changes to get your XSLT 2.0 transformation to work:
- Add
as="node()"
to thexsl:param
. - Match the root element of the (ignored) input XML and
<xsl:apply-templates select="$products"/>
from there to get started on the param XML. - Remove
$products
from thexs:apply-templates
of your other templates. - 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>
来源:https://stackoverflow.com/questions/27376438/xslt-param-identity-transform-without-input-xml