strange xml xpath xsl error:

Discussion in 'XML' started by Tjerk Wolterink, Nov 16, 2004.

  1. 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
     
    Tjerk Wolterink, Nov 16, 2004
    #1
    1. Advertising

  2. [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
     
    Tjerk Wolterink, Nov 16, 2004
    #2
    1. Advertising

  3. Tjerk Wolterink

    Joris Gillis Guest

    >
    > 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-view.cgi?userid=38041)
    Ceterum censeo XML omnibus esse utendum
     
    Joris Gillis, Nov 16, 2004
    #3
  4. 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?
     
    Tjerk Wolterink, Nov 16, 2004
    #4
  5. Tjerk Wolterink

    Joris Gillis Guest

    > 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-view.cgi?userid=38041)
    Ceterum censeo XML omnibus esse utendum
     
    Joris Gillis, Nov 17, 2004
    #5
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Kevin Flood
    Replies:
    0
    Views:
    1,023
    Kevin Flood
    Sep 8, 2004
  2. Kevin Flood
    Replies:
    1
    Views:
    2,741
    Kevin Flood
    Sep 13, 2004
  3. Marvin_123456

    "Memory leak" in javax.xml.xpath.XPath

    Marvin_123456, Jul 29, 2005, in forum: Java
    Replies:
    4
    Views:
    1,974
    jan V
    Jul 29, 2005
  4. Replies:
    1
    Views:
    3,613
    A. Bolmarcich
    May 27, 2005
  5. AR
    Replies:
    2
    Views:
    397
    William Park
    May 27, 2005
Loading...

Share This Page