XSL: pattern is empty

T

Tjerk Wolterink

I have an xsl file wich xsl:includes this file:

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:page="http://www.wolterinkwebdesign.com/xml/page"
xmlns:xc="http://www.wolterinkwebdesign.com/xml/xcontent">

<xsl:eek:utput method="xml" indent="yes"/>

<xsl:param name="absolute_url"/>
<xsl:param name="upload_url"/>

<!--
! Default template for an image
!
!-->
<xsl:template name="image">
<xsl:param name="max_width" select="200"/>
<xsl:param name="img"/>
<xsl:if test="$img[xc:width]">
<xsl:choose>
<xsl:when test="$img[xc:error]/">
<b><xsl:value-of select="$img/xc:error"/></b>
</xsl:when>
<xsl:eek:therwise>
<img>
<xsl:attribute name="src">
<xsl:value-of select="$upload_url"/>/<xsl:value-of select="current()"/>
</xsl:attribute>
<xsl:if test="$img/@width>$max_width">
<xsl:attribute name="width"><xsl:value-of select="$max_width"/></xsl:attribute>
</xsl:if>
</img>
</xsl:eek:therwise>
</xsl:choose>
</xsl:if>
</xsl:template>

<!--
! All html should remain html
!-->
<xsl:template match="*[namespace-uri(.) != namespace::xc]">
<xsl:copy>
<xsl:for-each select="@*">
<xsl:copy/>
</xsl:for-each>
<xsl:apply-templates select="./node()"/>
</xsl:copy>
</xsl:template>

</xsl:stylesheet>




But now i get teh folowing error:

array(7) {
["msgtype"]=>
string(5) "error"
["code"]=>
string(2) "19"
["module"]=>
string(9) "Sablotron"
["URI"]=>
string(36) "file://C:/webserver/xsl/standard.xsl"
["line"]=>
string(2) "22"
["node"]=>
string(20) "element ''"
["msg"]=>
string(16) "pattern is empty"
}

So on line 22:
line 22: <xsl:when test="$img[xc:error]/">
the patternt is empty.

But $img should be a variable to a node, i tried <xsl:when test="current()[xc:error]/">
But that does not work.

What i want to do is call the template with name "image" whenever some element is found,
i give that element as an param $img with the template named "image".

But my xsl file that the above xsl includes do not ever call the template named "image".
So why is there an error??!?!?!

What does "pattern is empty" realy mean?
 
J

Joris Gillis

<xsl:if test="$img[xc:width]">
Shouldn't that be <xsl:if test="$img/xc:width"/> ?
 
D

David Carlisle

But $img should be a variable to a node, i tried <xsl:when
test="current()[xc:error]/"> But that does not work.

if $img is your current node, then you can just say
test="xc:error"
which is simpler.
What does "pattern is empty" realy mean?

It is most odd that you get an error like that from that line (are your
sure your processor isn't confused about the line number) a pattern is a
specific XSLT construct that appears in match attributes and certain
attributes of xsl:number, but never appears in a select or test
attributes which always take an arbitrary XPath expression not a pattern.
<!--
! All html should remain html
!-->
<xsl:template match="*[namespace-uri(.) != namespace::xc]">
<xsl:copy>
<xsl:for-each select="@*">
<xsl:copy/>
</xsl:for-each>
<xsl:apply-templates select="./node()"/>
</xsl:copy>
</xsl:template>


You can write the body of that more simply (and equivalently) as


<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:apply-templates/>
</xsl:copy>

rather than test against the namespace axis it's probably simpler just
to have
<xsl:template match="*">

so that it matches everything. For the xc elements you can then have

<xsl:template match="xc:*">
which does whatever you want to do for those. This will have a higher
default priority so your default copy template will not apply to xc
elements.

David
 
D

David Carlisle

Joris Gillis said:
<xsl:if test="$img[xc:width]">
Shouldn't that be <xsl:if test="$img/xc:width"/> ?

the two constructs are equivalent.

Do you mean that the Xpath expressions return exactly same?
I would find that most unlikely.

unlikely or not, it's true:)

$img[xc:width] and $img/xc:width of course would select different
things, but when used as a test expression there is an implied boolean()
around them and
boolean($img[xc:width]) and boolean($img/xc:width)
are equivalent Xpath expressions.

they are true just in case the node sets supplied to boolean() are
non-empty, and in either case, that is true only if there is an element
in $img that has a child with name xc:width.

David
 
J

Joris Gillis

unlikely or not, it's true:)
$img[xc:width] and $img/xc:width of course would select different
things, but when used as a test expression there is an implied boolean()
around them and
boolean($img[xc:width]) and boolean($img/xc:width)
are equivalent Xpath expressions.

they are true just in case the node sets supplied to boolean() are
non-empty, and in either case, that is true only if there is an element
in $img that has a child with name xc:width.

Oh, that way. I understand:)
The implied boolean operator slipped my mind somehow...

regards,
 
T

Tjerk Wolterink

David said:
But $img should be a variable to a node, i tried <xsl:when
test="current()[xc:error]/"> But that does not work.


if $img is your current node, then you can just say
test="xc:error"
which is simpler.

Well, then here my question.
If i am in a xsl:template and there i call another template using xsl:call-template
Then does there exists a current() or . node in the call-template?

If-yes then the problem is somewhere else.
What does "pattern is empty" realy mean?


It is most odd that you get an error like that from that line (are your
sure your processor isn't confused about the line number) a pattern is a
specific XSLT construct that appears in match attributes and certain
attributes of xsl:number, but never appears in a select or test
attributes which always take an arbitrary XPath expression not a pattern.

<!--
! All html should remain html
!-->
<xsl:template match="*[namespace-uri(.) != namespace::xc]">
<xsl:copy>
<xsl:for-each select="@*">
<xsl:copy/>
</xsl:for-each>
<xsl:apply-templates select="./node()"/>
</xsl:copy>
</xsl:template>



You can write the body of that more simply (and equivalently) as


<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:apply-templates/>
</xsl:copy>

ok that's nice
rather than test against the namespace axis it's probably simpler just
to have
<xsl:template match="*">

so that it matches everything. For the xc elements you can then have

<xsl:template match="xc:*">
which does whatever you want to do for those. This will have a higher
default priority so your default copy template will not apply to xc
elements.

hmm, that was not my question, but the stylesheet is more complex that i have shown here,
and there are 5 different namespaces, so the way i do it is better for the job.
 
R

Richard Tobin

Tjerk Wolterink said:
If i am in a xsl:template and there i call another template using
xsl:call-template
Then does there exists a current() or . node in the call-template?

call-template does not change the current node.

-- Richard
 
T

Tjerk Wolterink

haha i found what i did wrong:
line 22: <xsl:when test="$img[xc:error]/">
the patternt is empty.

I forgot ti remove the / char at the end in the xpath expression: $img[xc:error]/
should be: $img[xc:error]
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads

XSL :: page value assignment 0
News Ticker 2
Problem in xml transformation using xslt 0
XSL node as string 1
xslt and namespaces 2
Inlining or de-xmlifying xml using XSLT 8
XSL Grouping 0
XSL Calculation 0

Members online

Forum statistics

Threads
473,982
Messages
2,570,185
Members
46,738
Latest member
JinaMacvit

Latest Threads

Top