Reputation: 30723
I've been battling this XSL (Saxon/Java) code for several hours now, and still can't figure it. I narrowed the problem down to this snippet:
<xsl:function name="my:fff" >
<xsl:element name="p0">
<p1 aaa='AAA' />
</xsl:element>
</xsl:function>
<xsl:function name="my:ggg">
<xsl:variable name="v" select="my:fff()" />
<!-- Debug messages -->
<xsl:message>
$v '<xsl:sequence select="$v" />'
$v/* '<xsl:sequence select="$v/*" />'
$v/*/@aaa '<xsl:value-of select="$v/*/@aaa" />'
$v/p0 '<xsl:sequence select="$v/p0" />'
</xsl:message>
...
</xsl:function>
The output printed by the in my:ggg
is as follows:
$v '<p0><p1 aaa="AAA"/></p0>'
$v/* '<p1 aaa="AAA"/>'
$v/*/@aaa 'AAA'
$v/p0 ''
The first three lines are fine. But the fourth line which outputs an empty string is weird. I mean, if $v
is <p0><p1 aaa="AAA"/></po>
(as indicated in the first line) then why is it that $v/p0
isn't <p1 aaa="AAA"/>
?
What am I missing?
Upvotes: 1
Views: 191
Reputation: 163322
You would find it easier to diagnose this kind of problem if you made a habit of always declaring the argument and return types of a function. That would force you to think about what my:fff returns. In this case it's a (parentless) element node: you can declare the result as as="element(p0)"
. It would then stick out much more clearly that a p0 element is unlikely to have any p0 children, so my:fff()/p0
is probably wrong.
Upvotes: 1
Reputation: 243449
Your reasoning would be OK if the my:fff()
function was returning a document node -- not an element (p0
that itself doesn't have a p0
child).
So, if you change the function to be the following:
<xsl:function name="my:fff" as="document-node()" >
<xsl:document>
<xsl:element name="p0">
<p1 aaa='AAA' />
</xsl:element>
</xsl:document>
</xsl:function>
And the complete transformation would be:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:my="my:my">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/">
<xsl:sequence select="my:ggg()"/>
</xsl:template>
<xsl:function name="my:fff" as="document-node()" >
<xsl:document>
<xsl:element name="p0">
<p1 aaa='AAA' />
</xsl:element>
</xsl:document>
</xsl:function>
<xsl:function name="my:ggg">
<xsl:variable name="v" select="my:fff()" />
<!-- Debug messages -->
<xsl:message>
$v '
<xsl:sequence select="$v" />
' $v/* '
<xsl:sequence select="$v/*" />
' $v/*/@aaa '
<xsl:value-of select="$v/*/@aaa" />
' $v/p0 '
<xsl:sequence select="$v/p0" />'
</xsl:message> ...
</xsl:function>
</xsl:stylesheet>
then applying this transformation on any XML document (not used), produces now the following debugging output:
$v '<p0><p1 xmlns:my="my:my" aaa="AAA"/></p0>'
$v/* '<p0><p1 xmlns:my="my:my" aaa="AAA"/></p0>'
$v/*/@aaa ''
$v/p0 '<p0><p1 xmlns:my="my:my" aaa="AAA"/></p0>'
which is probably what you want, with the exception of the aaa
attribute, which needs to be accessed as: $v/*/*/@aaa
Upvotes: 1
Reputation: 23373
$v
is the element returned by my:fff
, so it is the tag <p0>
including children. $v/p0
tries to select a <p0>
as child of the tag in $v
, which is empty as the tag <p0>
selected by $v
does not contain a <p0>
.
Upvotes: 1