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

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Hoi Wong

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

    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.xs l"/>

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

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

    [patientData.xsl]:

    <xsl:template name="patientDa ta">
    <birthyear>
    <xsl:value-of
    select="documen t('rpt_pat.xml' )//parameter[@name='PatientB irthYear']"/>
    </birthyear>
    <gender>
    <xsl:value-of
    select="documen t('rpt_pat.xml' )//parameter[@name='PatientG ender]"/>
    </gender>
    </xsl:template>


    Instead of specifying document('rpt_p at.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_p at.xml') node. Using <xsl:for-eachcan lead to
    whoever that reads my XSLT scripts into thinking that there are multiple
    instances of the document('rpt_p at.xml') node, adding confusion to the
    already huge chaos.

    I'd like to avoid <xsl:template match="(somethi ng)"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


  • Martin Honnen

    #2
    Re: [XSLT] How to establish a context node without &lt;xsl:for-each&gt;

    Hoi Wong wrote:
    <xsl:template name="patientDa ta">
    <birthyear>
    <xsl:value-of
    select="documen t('rpt_pat.xml' )//parameter[@name='PatientB irthYear']"/>
    </birthyear>
    <gender>
    <xsl:value-of
    select="documen t('rpt_pat.xml' )//parameter[@name='PatientG ender]"/>
    </gender>
    </xsl:template>
    >
    >
    Instead of specifying document('rpt_p at.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_p at.xml') node. Using <xsl:for-eachcan lead to
    whoever that reads my XSLT scripts into thinking that there are multiple
    instances of the document('rpt_p at.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="patientDa ta">
    <xsl:variable name="pat_doc" select="documen t('rpt_pat.xml' )"/>
    <birthyear>
    <xsl:value-of
    select="$pat_do c//parameter[@name='PatientB irthYear']"/>
    </birthyear>
    <gender>
    <xsl:value-of
    select="$pat_do c//parameter[@name='PatientG ender]"/>
    </gender>
    </xsl:template>
    --

    Martin Honnen

    Comment

    • Richard Tobin

      #3
      Re: [XSLT] How to establish a context node without &lt;xsl:for-each&gt;

      In article <gfrdkf$itq$1@n ews.stanford.ed u>,
      Hoi Wong <wonghoi@stanfo rd.eduwrote:
      >Instead of specifying document('rpt_p at.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_p at.xml') node. Using <xsl:for-eachcan lead to
      >whoever that reads my XSLT scripts into thinking that there are multiple
      >instances of the document('rpt_p at.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.

      Comment

      • David Carlisle

        #4
        Re: [XSLT] How to establish a context node without &lt;xsl:for-each&gt;

        Hoi Wong wrote:
        Instead of specifying document('rpt_p at.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="documen t('rpt_pat.xml' )"/>
        then you can use $rpt///parameter[@name='PatientB irthYear']

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


        <xsl:template name="patientDa ta">
        <birthyear>
        <xsl:value-of select="key('rp t','PatientBirt hYear',$rpt)"/>
        </birthyear>
        <gender>
        <xsl:value-of select="key('rp t','PatientGend er',$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

        --

        Comment

        • Hoi Wong

          #5
          Re: [XSLT] How to establish a context node without &lt;xsl:for-each&gt;

          "David Carlisle" <david-news@dcarlisle. demon.co.ukwrot e in message
          news:MnoUk.8390 5$s62.13489@new sfe01.ams2...
          Hoi Wong wrote:
          >
          >Instead of specifying document('rpt_p at.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="documen t('rpt_pat.xml' )"/>
          then you can use $rpt///parameter[@name='PatientB irthYear']
          >
          In xslt2 I'd do
          <xsl:variable name="rpt" select="documen t('rpt_pat.xml' )"/>
          <xsl:key name="rpt" match="paramete r" use="@name"/>
          then
          >
          >
          <xsl:template name="patientDa ta">
          <birthyear>
          <xsl:value-of select="key('rp t','PatientBirt hYear',$rpt)"/>
          </birthyear>
          <gender>
          <xsl:value-of select="key('rp t','PatientGend er',$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


          Comment

          Working...