I want to add a couple of elements at the end of an XML document, right before the closing of the root node, and I\'m using an XSL to do the transformation.
The source X
Try it this way?
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<!-- match the root element of unknown name -->
<xsl:template match="/*">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
<!-- add a new element at the end -->
<my-el>my content</my-el>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
If all you ever want to do is add the new element/s, then you could shorten this to:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- match the root element of unknown name -->
<xsl:template match="/*">
<xsl:copy>
<xsl:copy-of select="@*|node()"/>
<!-- add a new element at the end -->
<my-el>my content</my-el>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
In your example input, the root element - and by inheritance, all of its child nodes - is in a namespace. If you want the added element/s to be in the same namespace, use:
<xsl:element name="my-el" namespace="{namespace-uri()}">my content</xsl:element>
instead of:
<my-el>my content</my-el>
why doesn't it work if I put
<xsl:template match="/web-app">
(<web-app/>
is the document root node) instead of<xsl:template match="/*">
?
That too is the result of the root element being in a namespace. In order to address it by name, you need to assign a prefix to the namespace and use it in the XPpath expression selecting the node:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:jve="http://java.sun.com/xml/ns/javaee"
exclude-result-prefixes="jve">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- match the root element of known name -->
<xsl:template match="/jve:web-app">
<xsl:copy>
<xsl:copy-of select="@*|node()"/>
<!-- add a new element at the end -->
<my-el>my content</my-el>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Once you have defined the prefix, you can also use it to place the added element/s in the namespace bound to the prefix:
<!-- add a new element at the end -->
<jve:my-el>my content</jve:my-el>
Alternatively you could do:
<!-- add a new element at the end -->
<my-el xmlns="http://java.sun.com/xml/ns/javaee">my content</my-el>