I have a test XML file:
<?xml version="1.0" encoding="utf-8"?>
<foo>
<bar>test</bar>
</foo>
I am using this XSLT 3 template:
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:mode on-no-match="fail"/>
<xsl:template match="/">
This is a test.
</xsl:template>
</xsl:stylesheet>
That outputs as expected, because it found a root (and there should always be a root):
This is a test.
But if I try to match the document element in an absolute way:
…
<xsl:template match="/foo">
…
That fails; with Saxon 12.2 it says:
XTDE0555 No user-defined template rule in the unnamed mode matches the node /
In fact this doesn't work either:
…
<xsl:template match="foo">
…
How can I match on the document element of an XML document, preferably using an absolute XPath expression, using XSLT 3?
Update: A ha! If I change the template to this, using the catch-all from https://stackoverflow.com/a/3378562, it matches for /foo
:
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:template match="/foo">
This is a test.
</xsl:template>
<xsl:template match="*">
<xsl:message terminate="no">
WARNING: Unmatched element: <xsl:value-of select="name()"/>
</xsl:message>
<xsl:apply-templates/>
</xsl:template>
</xsl:stylesheet>
This successfully outputs:
This is a test.
It does not issue any warning. This tells me that /foo
must successfully be matching something (which I assume is the document element <foo>
).
I wanted a simple switch to say "fail if nothing matches instead of outputting the text of the entire document"; see Why does XSLT output all text by default? . Am I not using <xsl:mode on-no-match="fail"/>
correctly in the first example?
/
)." You mean to tell me that<xsl:template match="/foo">
does not match the document node? Then why does it work and outputThis is a test.
when I remove the<xsl:mode on-no-match="fail"/>
? – Jankey