RE: [xsl] XSL Problem

Subject: RE: [xsl] XSL Problem
From: "Michael Kay" <mhk@xxxxxxxxx>
Date: Wed, 11 Aug 2004 20:47:27 +0100
I think you are simply getting the operator precedences wrong.

a/b[p] means a/(b[p]), not (a/b)[p].

So the expression you want is

<xsl:copy-of select="(/root/one/two[@in])[1]"/>

Michael Kay

> -----Original Message-----
> From: Josh Canfield [mailto:joshcanfield@xxxxxxxxx] 
> Sent: 11 August 2004 19:28
> To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
> Subject: Re: [xsl] XSL Problem
> 
> When I was looking at this question I stumbled onto something that is
> confusing me, I'm hoping someone here can enlighten me.
> 
> Given this xml:
> 
> <?xml version="1.0" encoding="UTF-8"?>
> <root>
> <one>
>   <two in="1">2.1</two>
>   <two in="1">2.2</two>
>   <two in="1">2.3</two>
> </one>
> <one>
>   <two in="2">2.1</two>
>   <two in="2">2.2</two>
>   <two in="2">2.3</two>
> </one>
> <one>
>   <two in="3">2.1</two>
>   <two in="3">2.2</two>
>   <two in="3">2.3</two>
> </one>
> </root>
> 
> If I want to copy all of the "two" nodes with an "in" 
> attribute I could do this:
> <xsl:copy-of select="/root/one/two[@in]"/>
> 
> But if I want to get the first "two" node with an "in" attribute, why
> can't I do this?:
> <xsl:copy-of select="/root/one/two[@in][1]"/>
> 
> As I read the XPath spec, it seems to be saying that the second
> predicate should be evaluated using the context list and proximity
> position of the node set generated by the completion of the first
> predicate. Both XALAN and Saxon seem to be treating the previous as
> equivalent to this:
> <xsl:copy-of select="/root/one/two[@in and position()=1]"/>
> 
> Am I reading this incorrectly?
> 
> http://www.w3.org/TR/xpath#section-Location-Steps
> "The initial node-set is filtered by the first predicate to generate a
> new node-set; this new node-set is then filtered using the second
> predicate, and so on."
> http://www.w3.org/TR/xpath#predicates
> "The proximity position of a member of a node-set with respect to an
> axis is defined to be the position of the node in the node-set ordered
> in document order if the axis is a forward axis and ordered in reverse
> document order if the axis is a reverse axis. The first position is
> 1."
> 
> Thanks,
> Josh
> 
> 
> On Wed, 11 Aug 2004 08:34:30 +0100, Michael Kay <mhk@xxxxxxxxx> wrote:
> > You can select the first NatureInterestCd = LIEN, using the 
> predicate
> > 
> > AdditionalInterestInfo[NatureInterestCD='LIEN'][1]
> > 
> > In XPath 2.0 you can then exclude this from your result set 
> by using the
> > "except" operator, and similarly for the other exclusions.
> > 
> > It's harder to do "A except B" in XPath 1.0: EXSLT offers a 
> set:difference()
> > extension function, or you can use logic based on 
> generate-id() or on the
> > formula
> > 
> > A[count(.|B) != count(B)]
> > 
> > Alternatively, you can use a predicate such as
> > 
> > AdditionalInterestInfo[not(NatureInterestCD='LIEN' and
> > not(preceding-sibling::*[NatureInterestCD='LIEN']))]
> > 
> > Michael Kay 
> > 
> > 
> > 
> > > -----Original Message-----
> > > From: Dale Earnest [mailto:dale.earnest@xxxxxxxxxxxxxxxxxxxxxxx]
> > > Sent: 11 August 2004 01:01
> > > To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
> > > Subject: [xsl] XSL Problem
> > >
> > > I've run into a difficult xslt problem and I was hoping
> > > someone may have some insight.
> > >
> > > I have an XML structure that looks like this (the '...'s
> > > represent nodes that aren't directly relevant to the question
> > > and are omitted):
> > >
> > > <PersAutoInsurance>
> > >  <PersVeh>
> > >   ...
> > >   <AdditionalInterest>
> > >     <AdditionalInterestInfo>
> > >     <NatureInterestCd>ADDIN</NatureInterestCd>
> > >    </AdditionalInterestInfo>
> > >   </AdditionalInterest>
> > >   <AdditionalInterest>
> > >    ...
> > >    <AdditionalInterestInfo>
> > >     <NatureInterestCd>LIEN</NatureInterestCd>
> > >    </AdditionalInterestInfo>
> > >   </AdditionalInterest>
> > >   <AdditionalInterest>
> > >    ...
> > >    <AdditionalInterestInfo>
> > >     <NatureInterestCd>LIEN</NatureInterestCd>
> > >    </AdditionalInterestInfo>
> > >   </AdditionalInterest>
> > >  </PersVeh>
> > >  <PersVeh>
> > >   <AdditionalInterest>
> > >    ...
> > >    <AdditionalInterestInfo>
> > >     <NatureInterestCd>ADDIN</NatureInterestCd>
> > >    </AdditionalInterestInfo>
> > >   </AdditionalInterest>
> > >   <AdditionalInterest>
> > >    ...
> > >    <AdditionalInterestInfo>
> > >     <NatureInterestCd>LIEN</NatureInterestCd>
> > >    </AdditionalInterestInfo>
> > >   </AdditionalInterest>
> > >   <AdditionalInterest>
> > >    ...
> > >    <AdditionalInterestInfo>
> > >     <NatureInterestCd>AIL</NatureInterestCd>
> > >    </AdditionalInterestInfo>
> > >   </AdditionalInterest>
> > >  </PersVeh>
> > > </PersAutoInsurance>
> > >
> > > What I'm trying to do is select NatureInterestCd's based on
> > > the following criteria:
> > > 1) I cannot accept the first NatureInterestCd = LIEN for each
> > > vehicle (but may accept any subsequent for processing)
> > > 2) I cannot accept the first NatureInterestCd = AIL for each
> > > vehicle (but may accept any subsequent for processing)
> > > 2) I can accept any other node
> > >
> > > I attempted to use this type of statement to get the nodes
> > > and loop over them:
> > > <xsl:for-each
> > > select="PersAutoInsurance/PersVeh/AdditionalInterest/Additiona
> > > lInterestInfo[not(NatureInterestCd = 'LIEN') and
> > > not(NatureInterestCd = 'AIL')]">
> > >
> > > But that eliminates all nodes, not simply the first.  I tried
> > > adding in a position() qualifier, but that ended up only
> > > checking the first node in the whole node-set selected.
> > >
> > > I tried
> > > generate-id(PersAutoInsurance/PersVeh[1]/AdditionalInterest/Ad
> > ditionalInterestInfo[NatureInterestCd = 'LIEN'][1]) as that 
> XPATH returns
> > the LIEN I don't > want (I had to use it in another part of 
> the xsl), but
> > the ID
> > > it generated wasn't the same as the ID that was being
> > > generated when I looped over the all the NatureInterestCd's,
> > > so I couldn't eliminate the node based on that.
> > >
> > > I'm nearing my wits end on this problem and I was hoping that
> > > someone could give some insight into this problem.
> > >
> > > Dale Earnest

Current Thread