[XSLT] How to establish a context node without <xsl:for-each>

Discussion in 'XML' started by Hoi Wong, Nov 17, 2008.

  1. Hoi Wong

    Hoi Wong Guest

    I have an XSLT script collection that converts messed up XML to usuable XML.
    Instead of generic template matching, I want to establish a context node for
    some branches so that I don't have to rely on absolute path. Here's a
    simplified version of my work:


    [root.xsl]:
    <xsl:include href="common.xsl"/>

    <xsl:template match="/">
    <patientDisk>
    <xsl:call-template name="patientData"/>
    </patientDisk>
    </xsl:template>

    ==================================

    [patientData.xsl]:

    <xsl:template name="patientData">
    <birthyear>
    <xsl:value-of
    select="document('rpt_pat.xml')//parameter[@name='PatientBirthYear']"/>
    </birthyear>
    <gender>
    <xsl:value-of
    select="document('rpt_pat.xml')//parameter[@name='PatientGender]"/>
    </gender>
    </xsl:template>


    Instead of specifying document('rpt_pat.xml') every time using absolute
    paths, I could have used <xsl:for-each select=document('rpt_pat.xml')>.
    However, I'd like to avoid using this syntax because there's only one
    instance of document('rpt_pat.xml') node. Using <xsl:for-each> can lead to
    whoever that reads my XSLT scripts into thinking that there are multiple
    instances of the document('rpt_pat.xml') node, adding confusion to the
    already huge chaos.

    I'd like to avoid <xsl:template match="(something)"> because some tags have
    the same names in the messy XML files that I'm trying to parse, and they can
    be distinguished only by observing the hieracy (which branch that XML tag is
    under).

    Can anybody suggest a neat way to do that? Thanks in advance.

    -- Hoi
    Hoi Wong, Nov 17, 2008
    #1
    1. Advertising

  2. Hoi Wong wrote:

    > <xsl:template name="patientData">
    > <birthyear>
    > <xsl:value-of
    > select="document('rpt_pat.xml')//parameter[@name='PatientBirthYear']"/>
    > </birthyear>
    > <gender>
    > <xsl:value-of
    > select="document('rpt_pat.xml')//parameter[@name='PatientGender]"/>
    > </gender>
    > </xsl:template>
    >
    >
    > Instead of specifying document('rpt_pat.xml') every time using absolute
    > paths, I could have used <xsl:for-each select=document('rpt_pat.xml')>.
    > However, I'd like to avoid using this syntax because there's only one
    > instance of document('rpt_pat.xml') node. Using <xsl:for-each> can lead to
    > whoever that reads my XSLT scripts into thinking that there are multiple
    > instances of the document('rpt_pat.xml') node, adding confusion to the
    > already huge chaos.


    I don't think there is a way to change the current node without using
    apply-templates or for-each. If you want to shorten the code then using
    a variable could do e.g.


    <xsl:template name="patientData">
    <xsl:variable name="pat_doc" select="document('rpt_pat.xml')"/>
    <birthyear>
    <xsl:value-of
    select="$pat_doc//parameter[@name='PatientBirthYear']"/>
    </birthyear>
    <gender>
    <xsl:value-of
    select="$pat_doc//parameter[@name='PatientGender]"/>
    </gender>
    </xsl:template>
    --

    Martin Honnen
    http://JavaScript.FAQTs.com/
    Martin Honnen, Nov 17, 2008
    #2
    1. Advertising

  3. In article <gfrdkf$itq$>,
    Hoi Wong <> wrote:
    >Instead of specifying document('rpt_pat.xml') every time using absolute
    >paths, I could have used <xsl:for-each select=document('rpt_pat.xml')>.
    >However, I'd like to avoid using this syntax because there's only one
    >instance of document('rpt_pat.xml') node. Using <xsl:for-each> can lead to
    >whoever that reads my XSLT scripts into thinking that there are multiple
    >instances of the document('rpt_pat.xml') node, adding confusion to the
    >already huge chaos.


    Apply-templates and for-each are the only constructs that let you change
    the context node.

    I recommend using for-each with a comment to indicate that its only
    purpose is to set the context.

    -- Richard


    --
    Please remember to mention me / in tapes you leave behind.
    Richard Tobin, Nov 17, 2008
    #3
  4. Hoi Wong wrote:

    > Instead of specifying document('rpt_pat.xml') every time using absolute
    > paths,


    as others have said you can't change the current node without for-each
    or apply-templates, etc, however you could use a variable
    <xsl:variable name="rpt" select="document('rpt_pat.xml')"/>
    then you can use $rpt///parameter[@name='PatientBirthYear']

    In xslt2 I'd do
    <xsl:variable name="rpt" select="document('rpt_pat.xml')"/>
    <xsl:key name="rpt" match="parameter" use="@name"/>
    then


    <xsl:template name="patientData">
    <birthyear>
    <xsl:value-of select="key('rpt','PatientBirthYear',$rpt)"/>
    </birthyear>
    <gender>
    <xsl:value-of select="key('rpt','PatientGender',$rpt)"/>
    </gender>
    </xsl:template>

    The third argument of key doesn't exactly change the current node but it
    changes the effective node used for determing the key lookup, which has
    more or less the same effect here.

    David

    --
    http://dpcarlisle.blogspot.com
    David Carlisle, Nov 18, 2008
    #4
  5. Hoi Wong

    Hoi Wong Guest

    "David Carlisle" <> wrote in message
    news:MnoUk.83905$2...
    > Hoi Wong wrote:
    >
    >> Instead of specifying document('rpt_pat.xml') every time using absolute
    >> paths,

    >
    > as others have said you can't change the current node without for-each or
    > apply-templates, etc, however you could use a variable
    > <xsl:variable name="rpt" select="document('rpt_pat.xml')"/>
    > then you can use $rpt///parameter[@name='PatientBirthYear']
    >
    > In xslt2 I'd do
    > <xsl:variable name="rpt" select="document('rpt_pat.xml')"/>
    > <xsl:key name="rpt" match="parameter" use="@name"/>
    > then
    >
    >
    > <xsl:template name="patientData">
    > <birthyear>
    > <xsl:value-of select="key('rpt','PatientBirthYear',$rpt)"/>
    > </birthyear>
    > <gender>
    > <xsl:value-of select="key('rpt','PatientGender',$rpt)"/>
    > </gender>
    > </xsl:template>
    >
    > The third argument of key doesn't exactly change the current node but it
    > changes the effective node used for determing the key lookup, which has
    > more or less the same effect here.
    >
    > David
    >
    > --
    > http://dpcarlisle.blogspot.com


    Thanks for the hint.

    Unfortunately, the software that I'm using (namely MATLAB and the orphaned
    proprietary data converter from the vendor) only support XSLT 1.0.

    In fact, I was using the variables trick before hitting this forum so I'll
    stick to that because it's easier to debug than switching nodes.

    Cheers,
    Hoi
    Hoi Wong, Nov 21, 2008
    #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. Replies:
    0
    Views:
    1,375
  2. Ralf Wahner
    Replies:
    2
    Views:
    2,377
    Ralf Wahner
    Jul 15, 2003
  3. CB
    Replies:
    1
    Views:
    583
    Johannes Koch
    Oct 2, 2003
  4. Replies:
    1
    Views:
    3,565
    A. Bolmarcich
    May 27, 2005
  5. Tjerk Wolterink
    Replies:
    2
    Views:
    1,390
    Dimitre Novatchev
    Aug 24, 2006
Loading...

Share This Page