Re: [xsl] XSL Problem

Subject: Re: [xsl] XSL Problem
From: "M. David Peterson" <m.david@xxxxxxxxxx>
Date: Wed, 11 Aug 2004 12:53:24 -0600
Either way they are evaluated they are going to return the same node set (in this particular case at least).. take out the "in" attribute from the first "two" child element and see if the results are as you would expect...

<M:D/>

Josh Canfield wrote:

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