I'd like to add an element to a xml document and I'd like to pass as a parameter the path to the element.
sample.xml file:
<?xml version="1.0"?>
<stuff>
<element1>
<foo>2</foo>
<bar/>
</element1>
<element2>
<subelement/>
<bar/>
</element2>
<element1>
<foo/>
<bar/>
</element1>
</stuff>
Using:
xalan.exe -p myparam "element1" sample.xml addelement.xslt
I'd like the following result:
<?xml version="1.0"?>
<stuff>
<element1>
<foo>2</foo>
<bar/>
<addedElement/>
</element1>
<element2>
<subelement/>
<bar/>
</element2>
<element1>
<foo/>
<bar/>
<addedElement/>
</element1>
</stuff>
I've manage to write addelement.xslt, when hardcoding the path it works, but when I try to use parameter myparam in the match attribute I get:
XPathParserException: A node test was expected.
pattern = '$myparam/*[last()]' Remaining tokens are: ('$' 'myparam' '/' '*' '[' 'last' '(' ')' ']') (addelement.xslt, line 12, column 42)
addelement.xslt
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="2.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="element1/*[last()]">
<xsl:copy-of select="."/>
<addedElement></addedElement>
</xsl:template>
</xsl:stylesheet>
addelement.xslt with hardcoded path replaced
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:param name="myparam"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="$myparam/*[last()]">
<xsl:copy-of select="."/>
<addedElement></addedElement>
</xsl:template>
</xsl:stylesheet>
Thanks for helping
I don't think you can use variables/paramaters in matching templates like you have coded. Even this doesn't work
<xsl:template match="*[name()=$myparam]/*[last()]">
Instead, try changing the first matching template to as follows, so that the parameter check is inside the template code, not as part of the match statement.
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
<xsl:if test="local-name() = $myparam">
<addedElement/>
</xsl:if>
</xsl:copy>
</xsl:template>