Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > XML > strange xml xpath xsl error:

Reply
Thread Tools

strange xml xpath xsl error:

 
 
Tjerk Wolterink
Guest
Posts: n/a
 
      11-16-2004
I've xml code like this:

roles.xml:
<?xml version="1.0" encoding="ISO-8859-1"?>
<roles xmlns="http://www.wolterinkwebdesign.com/xml/roles">

<!--
! The admin role.
! And admin should have all permisions to do its task
!
!-->
<role id="admin" isadmin="true">
<name>Administrator</name>
<description>De Administrator kan alles verwijderen, toevoegen en bewerken op de site.</description>
<grants>
<for name="all">
<action name="edit" grant="true" />
<action name="new" grant="true" />
<action name="read" grant="true" />
</for>
</grants>
</role>

<!--
! A generic visitor role.
! Anybody who is not given a role explicit is a visitor
!-->
<role id="visitor" isvisitor="true">
<name>Bezoeker</name>
<description>Bezoeker van de site</description>
a
<grants>
b
<for name="all">
<action name="read" grant="true" />
<action name="edit" grant="true" />
</for>
<for name="gastenboek">
<action name="new" grant="true"/>
<action name="edit" grant="true" />
</for>
<for name="medewerkers">
<action name="new" grant="true"/>
</for>
<for name="files">
y
<action name="new" grant="true">d</action>
</for>
<for name="news">
<action name="new" grant="true"/>
</for>
</grants>
</role>

</roles>


XSL code like this:
ps, $roles is always the above roles.xml


<!--
This template below works on for example
<page:button-edit-delete module="files" id="3"/>
-->
<xsl:template match="page:button-edit-delete">
<xsl:if test="$roles/r:roles/r:role[@id=$role]/r:grants/r:for[@name=./@module]/r:action[@name='edit']/@grant='true' or $roles/r:roles/r:role[@id=$role]/r:grants/r:for[@name='all']/r:action[@name='edit']/@grant='true'">
<[cut]
</xsl:if>
</xsl:template>

<!--
This template below does NOT work on for example
<page:button-new module="files" id="3"/>
-->
<xsl:template match="page:button-new">
<!-- debug code -->
BUTTON NEW MATCHED!
<xsl:value-of select="./@module"/>
<xsl:copy-of select="$roles/r:roles/r:role[@id=$role]/r:grants/r:for[@name=./@module]"/>
<xsl:copy-of select="$roles/r:roles/r:role[@id=$role]/r:grants/r:for[@name='files']"/>
<!-- end debug code -->

<xsl:if test="$roles/r:roles/r:role[@id=$role]/r:grants/r:for[@name=./@module]/r:action[@name='new']/@grant='true' or $roles/r:roles/r:role[@id=$role]/r:grants/r:for[@name='all']/r:action[@name='new']/@grant='true'">
[cut]
</xsl:if>
</xsl:template>


Strange enough:
this works: <xsl:value-of select="./@module"/> output:files
this does not work:
<xsl:copy-of select="$roles/r:roles/r:role[@id=$role]/r:grants/r:for[@name=./@module]"/> output= ""
and this does work:
<xsl:copy-of select="$roles/r:roles/r:role[@id=$role]/r:grants/r:for[@name='files']"/>

I do not understend the if test in the second template is almost the same as in the first template, but the first template always works and
the second not..... i cannot find the error
 
Reply With Quote
 
 
 
 
Tjerk Wolterink
Guest
Posts: n/a
 
      11-16-2004
[cut]

i've had the following solution:

<!--
! Matches a new button
!-->
<xsl:template match="page:button-new">
<xsl:variable name="module" select="./@module"/>
<xsl:if test="$roles/r:roles/r:role[@id=$role]/r:grants/r:for[@name=$module]/r:action[@name='new']/@grant='true' or $roles/r:roles/r:role[@id=$role]/r:grants/r:for[@name='all']/r:action[@name='new']/@grant='true'">
<div class="new_button">
<form enctype="multipart/form-data" action="$php_self" method="post">
<input type="hidden" name="module" value="{@module}" />
<input type="hidden" name="name" value="{@multiple}" />
<input type="hidden" name="new_request" value="true" />
<input class="new_button" type="submit" value="Nieuw item toevoegen" />
</form>
</div>
</xsl:if>
</xsl:template>



But that is ugly!! I think it must be possible without the xsl:variable
 
Reply With Quote
 
 
 
 
Joris Gillis
Guest
Posts: n/a
 
      11-16-2004
>
> Strange enough:
> this works: <xsl:value-of select="./@module"/> output:files
> this does not work:
> <xsl:copy-of select="$roles/r:roles/r:role[@id=$role]/r:grants/r:for[@name=./@module]"/> output= ""
> and this does work:
> <xsl:copy-of select="$roles/r:roles/r:role[@id=$role]/r:grants/r:for[@name='files']"/>
>
> I do not understand the if test in the second template is almost the same as in the first template, but the first template always works and
> the second not..... i cannot find the error
>


Hi,


you could use this:
<xsl:copy-of select="$roles/r:roles/r:role[@id=$role]/r:grants/r:for[@name=current()/@module]"/>

Explanation:

In this Xpath expression:
<xsl:value-of select="./@module"/>
the period (.) selects the context node, which - in this case- is equal to the current node-set of the template.

But between the [brackets] in:
<xsl:copy-of select="/r:for[@name=./@module]"/>
, the context node is changed to the node preceding the left bracket ('r:for'). So this expression is trying to access the 'module' attribute of 'r:for'. In other words, you cannot access the current node-set with '.' when you're between brackets. You have to use 'current()' in stead.

regards,
--
Joris Gillis (http://www.ticalc.org/cgi-bin/acct-v...i?userid=38041)
Ceterum censeo XML omnibus esse utendum
 
Reply With Quote
 
Tjerk Wolterink
Guest
Posts: n/a
 
      11-16-2004
Joris Gillis wrote:
>>
>> Strange enough:
>> this works: <xsl:value-of select="./@module"/> output:files
>> this does not work:
>> <xsl:copy-of
>> select="$roles/r:roles/r:role[@id=$role]/r:grants/r:for[@name=./@module]"/>
>> output= ""
>> and this does work:
>> <xsl:copy-of
>> select="$roles/r:roles/r:role[@id=$role]/r:grants/r:for[@name='files']"/>
>>
>> I do not understand the if test in the second template is almost the
>> same as in the first template, but the first template always works and
>> the second not..... i cannot find the error
>>

>
> Hi,
>
>
> you could use this:
> <xsl:copy-of
> select="$roles/r:roles/r:role[@id=$role]/r:grants/r:for[@name=current()/@module]"/>
>
>
> Explanation:
>
> In this Xpath expression:
> <xsl:value-of select="./@module"/>
> the period (.) selects the context node, which - in this case- is equal
> to the current node-set of the template.
>
> But between the [brackets] in:
> <xsl:copy-of select="/r:for[@name=./@module]"/>
> , the context node is changed to the node preceding the left bracket
> ('r:for'). So this expression is trying to access the 'module' attribute
> of 'r:for'. In other words, you cannot access the current node-set with
> '.' when you're between brackets. You have to use 'current()' in stead.
>
> regards,


i thought of that, but i did not know current() existed.
But then how do you explain that this template works:

<xsl:template match="page:button-edit-delete">
<xsl:if test="$roles/r:roles/r:role[@id=$role]/r:grants/r:for[@name=./@module]/r:action[@name='edit']/@grant='true' or $roles/r:roles/r:role[@id=$role]/r:grants/r:for[@name='all']/r:action[@name='edit']/@grant='true'">
[cut]
</xsl:if>
</xsl:template>


And this one not:

<xsl:template match="page:button-new">
<xsl:if test="$roles/r:roles/r:role[@id=$role]/r:grants/r:for[@name=./@module]/r:action[@name='new']/@grant='true' or $roles/r:roles/r:role[@id=$role]/r:grants/r:for[@name='all']/r:action[@name='new']/@grant='true'">
[cut]
</xsl:if>
</xsl:template>


I do not understand that. the only differences ar in @name='edit' or @name='new' and in the match attribute of xsl:template.
Maybe i should give more detail?


 
Reply With Quote
 
Joris Gillis
Guest
Posts: n/a
 
      11-17-2004
> i thought of that, but i did not know current() existed.
> But then how do you explain that this template works:
>
> <xsl:template match="page:button-edit-delete">
> <xsl:if test="$roles/r:roles/r:role[@id=$role]/r:grants/r:for[@name=./@module]/r:action[@name='edit']/@grant='true' or $roles/r:roles/r:role[@id=$role]/r:grants/r:for[@name='all']/r:action[@name='edit']/@grant='true'">
> [cut]
> </xsl:if>
> </xsl:template>
>
>
> And this one not:
>
> <xsl:template match="page:button-new">
> <xsl:if test="$roles/r:roles/r:role[@id=$role]/r:grants/r:for[@name=./@module]/r:action[@name='new']/@grant='true' or $roles/r:roles/r:role[@id=$role]/r:grants/r:for[@name='all']/r:action[@name='new']/@grant='true'" [cut]
> </xsl:if>
> </xsl:template>
>
>
> I do not understand that. the only differences ar in @name='edit' or @name='new' and in the match attribute of xsl:template.

I'm not really sure either. One guess is that there's an 'action' node in your XML that does not have a 'name' attribute. That node would match the XPath expression because its non-existing 'name' attribute woulkd its non-existing 'module' attribute.

btw, I think it would be better to use a shorter notation like this:
<xsl:if test="//r:roles/r:role[@id=$role]/r:grants/r:for[@name='all' or @name=current()/@module]/r:action[@name='new']/@grant='true'">

regards,
--
Joris Gillis (http://www.ticalc.org/cgi-bin/acct-v...i?userid=38041)
Ceterum censeo XML omnibus esse utendum
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
XML/XSL/XPATH how to get a element value Kniffel XML 8 09-07-2007 03:26 PM
"Memory leak" in javax.xml.xpath.XPath Marvin_123456 Java 4 07-29-2005 03:49 PM
XSL Question tp xsl:for-each and xsl:variable schaf@2wire.ch XML 1 05-27-2005 09:25 PM
Strings of an xml element using XSL and XPath AR XML 2 05-27-2005 09:07 PM
Problem selecting a node with XPATH if attribute value contains backslashes - how to force XPATH string to be treated as literal? Alastair Cameron XML 1 07-08-2003 07:24 PM



Advertisments