Again a simple thing. I have a stylesheet that parses XML and XSL files. Basically, it tries to detect if the XML is a stylesheet with:
<xsl:if test="count(//xsl:template)!=0">
It does indeed detect stylesheets. It has problems with XML files, though, which generate an “Undefined namespace prefix – ‘xsl’” error. (In XmlSpy. Similar errors in the project I’m working on.)
I’m doing something wrong. Any suggestions on how to improve this stylesheet?
Some additional information: This is a stylesheet that’s meant to analyse other XML files, no matter what they contain. It should be able to transform itself even, and does so nicely. It has no problem transforming other (normal) stylesheets either. The problem arrives when I try to transform a regular XML file. Yet not all XML files…
As it turns out, the error is something else. The XML files that I tried to transform contain a processing instruction. This one: <?xml-stylesheet href="..\MyStylesheet.xsl" type="text/xsl"?>
The problem I have now is that when I process an XML file that contains this PI, the XSLT starts reporting the error about the undefined namespace prefix. So, how do I tell the XSLT processor to ignore this processing instruction?
Double check how you have declared the
xslnamespace and what namespace-prefix you have chosen.You need to ensure that the
xslnamespace prefix is defined in your stylesheet if you want to use it in your XPATH expressions. You will get that error when you try to use a namespace prefix that has not been declared.If it isn’t declared anywhere further up in the stylesheet(typically on the document element like this:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">), or if you have chosen a different namespace prefix (e.g. declared it as “xslt” like this:xmlns:xslt="http://www.w3.org/1999/XSL/Transform"), then when you attempt to reference “xsl” it won’t know what you are referring to.You can declare the
xslnamespace prefix on yourifstatement as a quick test:You can simplify your test condition to select the
xsl:templateelements, rather than evaluating thecount()of them. The results oftest="//xsl:template"will evaluate astrue()if something is selected, andfalse()if nothing is selected.In stylesheets
xsl:templateare top level constructs that are children of the document element. Rather than using//to recurse through every node in the XML document tree, you can use a more efficient XPATH expression: