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: "Michael Kay" <mike@xxxxxxxxxxxx>
Date: Fri, 19 May 2006 19:10:14 +0100
It needed a little bit of tweaking:

<?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(name/@attachpart)]">
            <record>
                <name><xsl:value-of
select="name"/></name>
                <attachingPart>
                    <xsl:value-of
select="current-group()[name/@attachpart]/number"/>
                </attachingPart>
            </record>
        </xsl:for-each-group> 
        </doc>
    </xsl:template>
        
</xsl:transform>

Michael Kay
http://www.saxonica.com/ 

> -----Original Message-----
> From: mysrdr-wrk@xxxxxxxxx [mailto:mysrdr-wrk@xxxxxxxxx] 
> Sent: 19 May 2006 18:19
> To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
> Subject: RE: [xsl] Select nodes with an attribute but not all 
> the nodes
> 
> 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