[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message]

Re: targeting the last element in a node or consecutiv

Subject: Re: targeting the last element in a node or consecutive elements
From: Chuck Bearden <cbearden@xxxxxxxx>
Date: Thu, 4 Jan 2007 16:00:04 -0600
Re:  targeting the last element in a node or consecutiv
Your second 'apply-templates' rule will omit text and comment nodes, 
but that may not be important to your use case.

I adapted Jarno Elovirta's tree walking design pattern [1] for your
problem.  It's rather verbose and probably overkill for your 
problem, but you can see that this pattern of node-by-node walking
is quite powerful and can be adapted to many uses.

[1] http://www.dpawson.co.uk/xsl/sect2/N4486.html#d5280e1102

--------------------------------------------------------------------
<?xml version="1.0"?>

<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
>

  <xsl:output indent="yes" method="xml"/>

  <xsl:template match="/">
    <xsl:apply-templates/>
  </xsl:template>

  <xsl:template match="somenode">
    <xsl:param name="nodeType">start</xsl:param>
    <xsl:copy>
      <xsl:apply-templates select="@*"/>
      <!-- Step into 'walk' mode and process first child node -->
      <xsl:apply-templates select="node()[1]" mode="walk">
        <xsl:with-param name="nodeType" select="$nodeType"/>
      </xsl:apply-templates>
    </xsl:copy>
  </xsl:template>

<!-- 'walk' mode templates -->

  <!-- 'walk' mode; PI with no elements in following-sibling axis -->
  <xsl:template match="processing-instruction()
      [not(following-sibling::*)]" mode="walk">
    <xsl:param name="nodeType"/>
    <xsl:if test="$nodeType='elem'">
    <!-- We are in the first PI after the last element; 
         do any special processing here -->
      <insertedElement/><xsl:text>
</xsl:text>
    </xsl:if>
    <!-- Apply default mode templates to this node -->
    <xsl:apply-templates select="."/>
    <!-- Walk on to next sibling node -->
    <xsl:apply-templates select="following-sibling::node()[1]" mode="walk">
      <xsl:with-param name="nodeType">pi</xsl:with-param>
    </xsl:apply-templates>
  </xsl:template>

  <!-- 'walk' mode; all other nodes -->
  <xsl:template match="node()" mode="walk">
    <xsl:param name="nodeType"/>
    <!-- Apply default mode templates to this node -->
    <xsl:apply-templates select="."/>
    <!-- Walk on to next sibling node -->
    <xsl:apply-templates select="following-sibling::node()[1]" mode="walk">
    <!-- Tell following templates which of element or pi was last seen -->
      <xsl:with-param name="nodeType">
        <xsl:choose>
          <xsl:when test="self::*">elem</xsl:when>
          <xsl:when test="self::processing-instruction()">pi</xsl:when>
          <xsl:otherwise><xsl:value-of select="$nodeType"/></xsl:otherwise>
        </xsl:choose>
      </xsl:with-param>
    </xsl:apply-templates>
  </xsl:template>

<!-- Default mode templates; standard identity transforms -->
  <xsl:template match="*">
    <xsl:copy>
      <xsl:apply-templates select="@*"/>
      <xsl:apply-templates/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="@*|text()|comment()">
    <xsl:copy/>
  </xsl:template>

  <xsl:template match="processing-instruction()">
  <!-- Special treatment for PIs? -->
    <xsl:copy/>
  </xsl:template>

</xsl:stylesheet>
--------------------------------------------------------------------

Chuck
--
Chuck Bearden ---------------------------------- C o n n e x i o n s
Sr. Content Specialist                        Rice University MS 375
cbearden@xxxxxxxx                                        PO Box 1892
AIM: Schleifheim                              Houston, TX 77251-1892
713.348.3661 (voice) --- <http://cnx.org/> ------ (fax) 713.348.3665

> From: egarrett@xxxxxxxxxxxx <egarrett@xxxxxxxxxxxx>
> Date: Jan 4, 2007 2:42 PM
> Subject: Re:  targeting the last element in a node or consecutive 
> elements
> To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
> 
> 
> This appears to be working:
> 
>               <xsl:apply-templates select="node()[not(self::processing-
> instruction()[not(following-sibling::*)])]"/>
> 
> Then I insert the extra element.  Then grab the PIs I suppressed above:
>               <xsl:apply-templates select="node()[self::processing-
> instruction()[not(following-sibling::*)]]"/>
> 
> Does it look right?
> 
> Thanks.
> --emily
> 
> ----- Original Message -----
> From: <egarrett@xxxxxxxxxxxx>
> Date: Thursday, January 4, 2007 2:21 pm
> Subject: Re:  targeting the last element in a node or consecutive
> elements
> To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
> 
> >Here is my logic so far to target everything in the node, and if
> >it is
> >a processing-instruction it should be processed only if something
> >exists after it other than another processing-instruction.  What I
> >have
> >below does not work because I think it is looking for the second
> >processing-instruction inside the first one rather than following
> >it,
> >but it is starting to feel like it is possible to put what I need
> >in
> >one instruction.
> >
> ><xsl:apply-templates select="node()[not(self::processing-instruction()
> >[not(following::*[not(self::processing-instruction())])])]"/>
> >
> >Warning: on line 58 of file:/C:/Documents%20and%
> >20Settings/egarrett/Desktop/Transforms%20R%20Us/saxon/xsl/X3B.xsl:
> > The self axis will never select any element() nodes when
> >starting at
> >an
> > processing-instruction() node
> >
> >Any ideas?
> >----- Original Message -----
> >From: egarrett@xxxxxxxxxxxx
> >Date: Thursday, January 4, 2007 9:59 am
> >Subject: Re:  targeting the last element in a node or
> >consecutive
> >elements
> >To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
> >
> >> Yes, your example is correct.  I don't know if or how many PIs
> >> will
> >> occur at the end of the node.
> >>
> >> P.S. I started a new post because they changed the
> >> requirements....
> >>
> >> ----- Original Message -----
> >> From: Abel Braaksma <abel.online@xxxxxxxxx>
> >> Date: Thursday, January 4, 2007 9:53 am
> >> Subject: Re:  targeting the last element in a node or
> >> consecutive
> >> elements
> >> To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
> >>
> >> > Hi Emily,
> >> >
> >> > This is a double post, you already opened this discussion
> >under
> >> > "suppressing only the last PI" (which differed in details,
> >however).> >
> >> > If I may, it appears that you want to do this:
> >> >
> >> > <somenode>
> >> >    <node1 />
> >> >    <?instr1?>
> >> >    <node2 />
> >> >    <?instr2?>
> >> >    <?instr3?>
> >> > </somenode>
> >> >
> >> > 1. Process node1, instr1, node2 etc
> >> > 2. Do something before instr2 and instr3 (being consecutively
> >> and
> >> > together at the end of a node)
> >> > 3. Process instr2 and instr3
> >> > (if instr2 and instr3 were not there, you want to skip
> >> processing
> >> > step 2
> >> > and 3?)
> >> >
> >> > Am i right? Please confirm (and/or give your sample input, to
> >> make
> >> > the
> >> > subject easier)
> >> >
> >> > Cheers,
> >> > -- Abel
> >> >
> >> > Emily.Garrett@xxxxxxxxxxx wrote:
> >> > > I'm trying to use xsl:apply templates to grab the entire
> >> content
> >> > of a
> >> > > node, except for any PIs that may be at the very end of the
> >> > node.  I can
> >> > > see how position()=last() can be used to refer to the very
> >> last
> >> > PI, but
> >> > > how would I refer to possibly 2 or 3 PIs that are at the end
> >> of
> >> > the node
> >> > > (not knowing what they are or how many), but still process
> >PIs
> >> > that are
> >> > > contained elsewhere in this content?   Is there some syntax
> >> that
> >> > refers> to consecutive elements or refers to an element that
> >is
> >> > the last one in
> >> > > a node, not knowing what element it is?
> >> > >
> >> > > Here is explanation for what I'm trying to do:
> >> > >
> >> > > Process all content, unless they are PIs that occur
> >> > consecutively at the
> >> > > very end of the node.
> >> > >
> >> > > Then I have to insert an element, then process these PIs
> >that
> >> occur> > consecutively at the very end of the node.
> >> > >
> >> > > I'm having trouble narrowing down my research on this one.
> >> Does
> >> > anyone> have any ideas?
> >> > >
> >> > > Thanks,
> >> > > Emily

Current Thread

PURCHASE STYLUS STUDIO ONLINE TODAY!

Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced!

Buy Stylus Studio Now

Download The World's Best XML IDE!

Accelerate XML development with our award-winning XML IDE - Download a free trial today!

Don't miss another message! Subscribe to this list today.
Email
First Name
Last Name
Company
Subscribe in XML format
RSS 2.0
Atom 0.3
Site Map | Privacy Policy | Terms of Use | Trademarks
Free Stylus Studio XML Training:
W3C Member
Stylus Studio® and DataDirect XQuery™are products from DataDirect Technologies, is a registered trademark of Progress Software Corporation, in the U.S. and other countries. © 2004-2007 All Rights Reserved.