Reputation: 8162
I would like to modify attribute value of element with name "FOO", so I wrote:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="FOO/@extent">
<xsl:attribute name="extent">
<xsl:text>1.5cm</xsl:text>
</xsl:attribute>
</xsl:template>
</xsl:stylesheet>
This stuff works. At now I need the same thing, but with element "fs:BOO". I tried replace FOO with "fs:BOO", but xsltproc say that it can not compile such code. I temporary solve this problem in such way:
sed 's|fs:BOO|fs_BOO|g' | xsltproc stylesheet.xsl - | sed 's|fs_BOO|fs:BOO|g'
but may be there is more simple solution, without usage of "sed"?
Example of input data:
<root>
<fs:BOO extent="0mm" />
</root>
if write:
<xsl:template match="fs:BOO/@extent">
I got:
xsltCompileStepPattern : no namespace bound to prefix fs
compilation error: file test.xsl line 10 element template
xsltCompilePattern : failed to compile 'fs:BOO/@extent'
Upvotes: 0
Views: 813
Reputation: 70648
Firstly, I would expect your XML to have a declaration for the namespace, otherwise it will not be valid
<root xmlns:fs="www.foo.com">
<fs:BOO extent="0mm" />
</root>
And this also applies to your XSLT. If you are trying to do <xsl:template match="fs:BOO/@extent">
then you need a declaration to the namespace in your XSLT too.
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fs="www.foo.com">
The important thing is the the namespace URI matches the one in the XML.
If, however, you want to cope with different namespaces, you can take a different approach. You could use the local-name() function to check the name of element without the namespace prefix.
Try this XSLT
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*[local-name()='BOO']/@extent">
<xsl:attribute name="extent">
<xsl:text>1.5cm</xsl:text>
</xsl:attribute>
</xsl:template>
</xsl:stylesheet>
This should output the following
<root xmlns:fs="fs">
<fs:BOO extent="1.5cm"></fs:BOO>
</root>
Upvotes: 1