RE: [xsl] Using key and position()

Subject: RE: [xsl] Using key and position()
From: Bhupendra Singh <skbhupendra@xxxxxxxxxxx>
Date: Wed, 17 Nov 2004 16:06:12 +0000 (GMT)
Hi Micheal,
Thanks for the advice. 

I have an input XML like this:

<action>
  - <ParentGroup Desc> Desc Node1 </ParentGroup Desc>
  - <ParentGroup> Node1 </ParentGroup>
  - <ChildGroup> Node1.1 </ChildGroup>
  - <Child Node1>1.1.1 </Child Node1>
  - <Child Node2>1.1.2 </Child Node2>
  - <Child Node3>1.1.3 </Child Node3>	
  - <ParentGroup Desc> Desc Node1 </ParentGroup Desc>
  - <ParentGroup> Node1 </ParentGroup>
  - <ChildGroup> Node1.2 </ChildGroup>
  - <Child Node1>1.2.1 </Child Node1>
  - <Child Node2>1.2.2 </Child Node2>
  - <Child Node3>1.2.3 </Child Node3>	
  - <ParentGroup Desc> Desc Node1 </ParentGroup Desc>
  - <ParentGroup> Node1 </ParentGroup>
  - <ChildGroup> Node1.3 </ChildGroup>
  - <Child Node1>1.3.1 </Child Node1>
  - <Child Node2>1.3.2 </Child Node2>
  - <Child Node3>1.3.3 </Child Node3>	
  - <ParentGroup Desc> Desc Node1 </ParentGroup Desc>
  - <ParentGroup> Node1 </ParentGroup>
  - <ChildGroup> Node1.3 </ChildGroup>
  - <Child Node1>1.3.x </Child Node1>
  - <Child Node2>1.3.y </Child Node2>
  - <Child Node3>1.3.z </Child Node3>	
  
  - <ParentGroup Desc> Desc Node2 </ParentGroup Desc>
  - <ParentGroup> Node2 </ParentGroup>
  - <ChildGroup> Node2.1 </ChildGroup>
  - <Child Node1>2.1.1 </Child Node1>
  - <Child Node2>2.1.2 </Child Node2>
  - <Child Node3>2.1.3 </Child Node3>	
  - <ParentGroup Desc> Desc Node2 </ParentGroup Desc>
  - <ParentGroup> Node2 </ParentGroup>
  - <ChildGroup> Node1.2 </ChildGroup>
  - <Child Node1>2.2.1 </Child Node1>
  - <Child Node2>2.2.2 </Child Node2>
  - <Child Node3>2.2.3 </Child Node3>	
  - <ParentGroup Desc> Desc Node2 </ParentGroup Desc>
  - <ParentGroup> Node2 </ParentGroup>
  - <ChildGroup> Node2.3 </ChildGroup>
  - <Child Node1>2.3.1 </Child Node1>
  - <Child Node2>2.3.2 </Child Node2>
  - <Child Node3>2.3.3 </Child Node3>	
..........
</action>

Please Note: All the above nodes are at the same
level. I have to change the input XML level wise like
this:

<Document>
 <ParentGroup Node1>
  <PRIMARY_CUST_DESC>Desc Node1</PRIMARY_CUST_DESC>
  <ChildGroup Node1.1 >
	<ACCOUNT_SUMMARY>
	- <Child Node1>1.1.1 </Child Node1>
	- <Child Node2>1.1.2 </Child Node2>
	- <Child Node3>1.1.3 </Child Node3>
	<ACCOUNT_SUMMARY>
  </ChildGroup>
  <ChildGroup Node1.2 >
	<ACCOUNT_SUMMARY>
	- <Child Node1>1.2.1 </Child Node1>
	- <Child Node2>1.2.2 </Child Node2>
	- <Child Node3>1.2.3 </Child Node3>
	</ACCOUNT_SUMMARY>
  </ChildGroup>
  <ChildGroup Node1.3 >
	<ACCOUNT_SUMMARY>
	- <Child Node1>1.3.1 </Child Node1>
	- <Child Node2>1.3.2 </Child Node2>
	- <Child Node3>1.3.3 </Child Node3>
	</ACCOUNT_SUMMARY>
	<ACCOUNT_SUMMARY>
	- <Child Node1>1.3.x </Child Node1>
	- <Child Node2>1.3.y </Child Node2>
	- <Child Node3>1.3.z </Child Node3>
	</ACCOUNT_SUMMARY>
  </ChildGroup>
 </ParentGroup>	
 <ParentGroup Node2>	
 <PRIMARY_CUST_DESC>Desc Node1</PRIMARY_CUST_DESC>
  <ChildGroup Node2.1 >
	<ACCOUNT_SUMMARY>
	- <Child Node1>2.1.1 </Child Node1>
	- <Child Node2>2.1.2 </Child Node2>
	- <Child Node3>2.1.3 </Child Node3>
	</ACCOUNT_SUMMARY>
  </ChildGroup>
  <ChildGroup Node1.2 >
	<ACCOUNT_SUMMARY>
	- <Child Node1>2.2.1 </Child Node1>
	- <Child Node2>2.2.2 </Child Node2>
	- <Child Node3>2.2.3 </Child Node3>
	</ACCOUNT_SUMMARY>
  </ChildGroup>
  <ChildGroup Node2.3 >
	<ACCOUNT_SUMMARY>
	- <Child Node1>2.3.1 </Child Node1>
	- <Child Node2>2.3.2 </Child Node2>
	- <Child Node3>2.3.3 </Child Node3>
	</ACCOUNT_SUMMARY>
  </ChildGroup>
 </ParentGroup>	
...........
</Document>


Please Note these constraints:
 - If you see I have only 2 distinct ParentGroups
   <ParentGroup> Node1 </ParentGroup> and
   <ParentGroup> Node2 </ParentGroup>
 - I have two <ChildGroup> Node1.3 </ChildGroup> 
   under <ParentGroup Node1>
   So I have to further sub-group on the ChildGroups


With the 
 <xsl:for-each-group group-starting-with="ParentGroup"

I get all the <ParentGroup> groups (I have 162 in
total)..but then I am not able to further find the
distinct <ParentGroup> (which should be 2)
After that I have to further sub-group on the
ChildGroups


Using preceding-sibling I am able to find the position
and then I can group these correctly
but its taking a hell lot of time to process.

regards,
Bhupendra.







 --- Michael Kay <mike@xxxxxxxxxxxx> wrote: 
> Firstly, $p is a node-set, whereas you appear to be
> using it in a predicate
> as if it were a number. When $p is a node-set,
> $seq[$p] will give you all
> the nodes in $seq if $p is non-empty, or none of the
> nodes in $seq if it is
> empty. You almost certainly meant to write
> $seq[number($p)].
> 
> However, if $var_27[$p] is displaying nothing, then
> there must be yet
> another bug in your code, because it means that
> either $p is empty (in which
> case number($p) isn't going to be useful) or $var_27
> is empty (in which case
> selecting it's $p'th item isn't going to do any
> good).
> 
> I've found it: you're calling key() with
> generate-id() as the second
> argument, but the nodes are indexed on the value of
> @id. There's no reason
> why the generate-id() of a node should match the @id
> attribute - you seem to
> be confused about its purpose.
> 
> As I suggested before, I think you would be better
> off explaining the
> problem you are trying to solve, because I strongly
> suspect the way you are
> going about it might be completely wrong.
> 
> Michael Kay
> http://www.saxonica.com/
>  
> 
> > -----Original Message-----
> > From: Bhupendra Singh
> [mailto:skbhupendra@xxxxxxxxxxx] 
> > Sent: 16 November 2004 21:08
> > To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
> > Subject: RE: [xsl] Using key and position()
> > 
> > Michael,
> > My problem is something else.
> > 
> > I am not able to access the variable. So I am
> getting
> > an undefined value for $p
> > 
> > <xsl:variable name="p" select="key('parentGroups',
> > generate-id())/@pos" />
> > 
> > I think the problem is with the key/variable
> > definition, which is giving nothing for $p.
> > 
> > Your suggestion below will be useful only if I get
> > some value of $p.
> > But currently the <xsl:value-of select="$p"/> is
> > printing a blank.
> > 
> > 
> > <PRI_HEADER><xsl:value-of select="$p"/>
> >    <xsl:value-of select="$var_27[$p]"/>
> > </PBU_HEADER>
> > 
> > 
> >  --- Michael Kay <mike@xxxxxxxxxxxx> wrote: 
> > > position() returns the position of a node in the
> > > list of nodes that you are
> > > currently iterating over. So
> > > 
> > > <xsl:variable name="parentGroup">
> > >   <xsl:for-each select="ParentGroup">
> > >     <parentgroup id="generate-id()"
> > > pos="position()"/>
> > >   </xsl:for-each>
> > > </xsl:variable>
> > > 
> > > will give you values 1,2,3 etc.
> > > 
> > > You will get what you are looking for by:
> > > 
> > > <xsl:variable name="parentGroup">
> > >   <xsl:for-each select="*">
> > >     <xsl:if test="self::parentGroup">
> > >        <parentgroup id="generate-id()"
> > > pos="position()"/>
> > >     </xsl:if>
> > >   </xsl:for-each>
> > > </xsl:variable>
> > > 
> > > However, there might be a much easier way of
> doing
> > > what you are trying to
> > > do, if you explained your overall problem rather
> > > than your approach to
> > > solving it.
> > > 
> > > Michael Kay
> > > http://www.saxonica.com/
> > > 
> > > > -----Original Message-----
> > > > From: Bhupendra Singh
> > > [mailto:skbhupendra@xxxxxxxxxxx] 
> > > > Sent: 16 November 2004 16:13
> > > > To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
> > > > Subject: [xsl] Using key and position()
> > > > 
> > > > Hi,
> > > > I have an input XML like this:
> > > > 
> > > > <action>
> > > > 	- <ParentGroup> Node1 </ParentGroup>
> > > > 	- <ChildGroup> Node1.1 </ChildGroup>
> > > > 	- <Child Node1>1.1.1 </Child Node1>
> > > > 	- <Child Node2>1.1.2 </Child Node2>
> > > > 	- <ParentGroup> Node1 </ParentGroup>
> > > > 	- <ChildGroup> Node1.2 </ChildGroup>
> > > > 	- <Child Node1>1.2.1 </Child Node1>
> > > > 	- <Child Node2>1.2.2 </Child Node2>
> > > > 	- <ParentGroup> Node1 </ParentGroup>
> > > > 	- <ChildGroup> Node1.3 </ChildGroup>
> > > > 	- <Child Node1>1.3.1 </Child Node1>
> > > > 	- <Child Node2>1.3.2 </Child Node2>
> > > > 	- <ParentGroup> Node1 </ParentGroup>
> > > > 	- <ChildGroup> Node1.3 </ChildGroup>
> > > > 	- <Child Node1>1.3.x </Child Node1>
> > > > 	- <Child Node2>1.3.y </Child Node2>
> > > > 
> > > > 	- <ParentGroup> Node2 </ParentGroup>
> > > > 	- <ChildGroup> Node2.1 </ChildGroup>
> > > > 	- <Child Node1>2.1.1 </Child Node1>
> > > > 	- <Child Node2>2.1.2 </Child Node2>
> > > > 	- <ParentGroup> Node2 </ParentGroup>
> > > > 	- <ChildGroup> Node2.2 </ChildGroup>
> > > > 	- <Child Node1>2.2.1 </Child Node1>
> > > > 	- <Child Node2>2.2.2 </Child Node2>
> > > > 	- <ParentGroup> Node2 </ParentGroup>
> > > > 	- <ChildGroup> Node2.3 </ChildGroup>
> > > > 	- <Child Node1>2.3.1 </Child Node1>
> > > > 	- <Child Node2>2.3.2 </Child Node2>
> > > > ...........
> > > > </action>
> > > > 
> > > > I want to capture the position of each of the
> > > > <ParentGroup> elements and store it in a
> variable
> > > by
> > > > going through the document only once. 
> > > > 
> > > > <xsl:variable name="parentGroup">
> > > >   <xsl:for-each select="ParentGroup">
> > > >     <parentgroup id="generate-id()"
> > > pos="position()"/>
> > > >   </xsl:for-each>
> > > > </xsl:variable>
> > > > 
> > > > 
> > > > Then I want to use this variable to get the
> > > position
> > > > of each <ParentGroup> and find its
> coresponding
> > > > <ChildGroup> and <Child Nodes>.
> > > > 
> > > > When I print the contents of the variable(@id
> and
> > > > @pos), then I find that the content is
> correct,
> > > but
> > > > when I try to retreive the content using key
> then
> > > I
> > > > get nothing.  Here is the XSL that I have.
> > > > 
> > > > 
> > > > <?xml version="1.0" ?>
> > > > <xsl:stylesheet
> > > >
> xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
> > > > version="1.0">
> > > > 
> > > > <!-- Key to group distinct ChildGroup's -->
> > > > <xsl:key name="SEC_CUST" match="ChildGroup"
> > > use="."/>
> > > > 
> > > > <!-- Key to group distinct ParentGroup's -->
> > > > <xsl:key name="PRI_CUST" match="ParentGroup"
> > > use="."/>
> > > > 
> > > > <!-- Key to find position of ParentGroup's -->
> > > > <xsl:key name="parentGroups"
> match="parentGroup"
> > > > use="@id"/>
> > > > 
> > > > <xsl:template match="/">
> > > > 	<xsl:apply-templates/>
> > > > </xsl:template>
> > > > 
> > > > 
> > > > <xsl:template match="action">
> 
=== message truncated === 

________________________________________________________________________
Yahoo! India Matrimony: Find your life partner online
Go to: http://yahoo.shaadi.com/india-matrimony

Current Thread