RE: [xsl] Select nodes with an attribute but not all the nodes

Subject: RE: [xsl] Select nodes with an attribute but not all the nodes
From: <mysrdr-wrk@xxxxxxxxx>
Date: Fri, 19 May 2006 10:19:03 -0700 (PDT)
I was thinking sequentially...down the elements as
they occur. 

When I tried your suggestion the <number> element came
up blank. Did I do this correctly?

XSL:
<?xml version="1.0" encoding="utf-8"?>
<xsl:transform version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>
    
    <xsl:output indent="yes" method="xml"
omit-xml-declaration="no"
        encoding="UTF-8"/>
    
    <xsl:template match="doc">
        <doc>
        <xsl:for-each-group select="level2"
            group-starting-with="*[not(@attachpart)]">
            <record>
                <name><xsl:value-of
select="name"/></name>
                <attachingPart>
                    <xsl:value-of
select="current-group()[@attachpart]/number"/>
                </attachingPart>
            </record>
        </xsl:for-each-group> 
        </doc>
    </xsl:template>
        
</xsl:transform>

XML:
<?xml version="1.0" encoding="UTF-8"?>
<doc>
<level2>
    <name>box</name>
    <number>1234</number>
</level2>
 <level2>
      <name attachpart = '1'>washer</name>
          <number>234</number>
  </level2>
  <level2>
      <name attachpart = '1'>screw</name>
          <number>345</number>
  </level2>
  <level2>
      <name attachpart='1'>bolt</name>
          <number>456</number>
  </level2>
  <level2>
      <name>nameplate</name>
      <number>9876</number>
  </level2>
  <level2>
      <name>switch</name>
      <number>7654</number>
  </level2>
  <level2>
      <name attachpart='1'>screw</name>
          <number>345</number>
  </level2>
</doc>

OUTPUT:
<?xml version="1.0" encoding="UTF-8"?>
<doc>
   <record>
      <name>box</name>
      <attachingPart/>
   </record>
   <record>
      <name>washer</name>
      <attachingPart/>
   </record>
   <record>
      <name>screw</name>
      <attachingPart/>
   </record>
   <record>
      <name>bolt</name>
      <attachingPart/>
   </record>
   <record>
      <name>nameplate</name>
      <attachingPart/>
   </record>
   <record>
      <name>switch</name>
      <attachingPart/>
   </record>
   <record>
      <name>screw</name>
      <attachingPart/>
   </record>
</doc>

Thanks for your help.

Regard
Hermy

--- Michael Kay <mike@xxxxxxxxxxxx> wrote:

> It's dangerous to use the word "when" in your
> problem statement because it
> suggests you are thinking in terms of order of
> execution.
> 
> What you've got here is a positional grouping
> problem:
> 
> <xsl:for-each-group select="level2"
> group-starting-with="*[not(@attachpart)]">
> <record>
>   <name><xsl:value-of select="name"/></name>
>   <attachingPart>
>     <xsl:value-of
> select="current-group()[@attachpart]/number"/>
>   </attachingPart>
> </record>
> </xsl:for-each> 
> 
> Michael Kay
> http://www.saxonica.com/
> 
> > -----Original Message-----
> > From: mysrdr-wrk@xxxxxxxxx
> [mailto:mysrdr-wrk@xxxxxxxxx] 
> > Sent: 19 May 2006 17:06
> > To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
> > Subject: [xsl] Select nodes with an attribute but
> not all the nodes
> > 
> > I am making an XML to XML transform using XSLT 2.0
> and Saxon 
> > 8B.  I need to select certain nodes based on an
> attribute, 
> > but when I find a node without the attribute I
> want to stop 
> > selecting nodes even if subsequent siblings have
> the attribute.  
> >    
> >   <level2>
> >               <name>box</name>
> >               <number>1234</number>
> >   </level2>
> >   <level2>
> >               <name attachpart="1">washer</name>
> >               <number>234</number>
> >   </level2>
> >   <level2>
> >               <name attachpart="1">screw</name>
> >               <number>345</number>
> >   </level2>
> >   <level2>
> >               <name attachpart="1">bolt</name>
> >               <number>456</number>
> >   </level2>
> >   <level2>
> >               <name>nameplate</name>
> >               <number>9876</number>
> >   </level2>
> >   <level2>
> >               <name>switch</name>
> >               <number>7654</number>
> >   </level2>
> >   <level2>
> >               <name attachpart="1">screw</name>
> >               <number>345</number>
> >   </level2>
> >    
> >   The washer screw and bold are attaching parts
> for the box. 
> > I need to output these in an <attachingPart>
> element.  
> >    
> >   <record>
> >               <name>box</name>
> >               <attachingPart>234 345
> > 456</attachingPart>
> >   </record>
> >    
> >   Depending on how I approach the code, I get
> nothing or just 
> > the washer or I get *all* of the parts that have
> the 
> > attachpart attribute.  Is there some way to say
> stop 
> > selecting attachpart nodes when a level2 doesn't
> have the 
> > attribute?  It's sounds so simple but I'm not
> getting 
> > anywhere with it. 
> >  
> > I've been reading both Michael and Jeni and
> checking the 
> > archives.  Some things look close but I get the
> same results. 
> > The answer is probably right in front of my face
> but I've 
> > been looking at it so long I can't see the forest
> for the trees.
> >    
> >   Regards,
> >   Hermy

Current Thread