xsl-list
[Top] [All Lists]

RE: Using key and position()

2004-11-16 21:42:04
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(_at_)yahoo(_dot_)co(_dot_)uk] 
Sent: 16 November 2004 21:08
To: xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com
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(_at_)saxonica(_dot_)com> 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(_at_)yahoo(_dot_)co(_dot_)uk] 
Sent: 16 November 2004 16:13
To: xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com
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">
<TRANS_OUTPUT>
<CUSTOMERS>
<xsl:variable name="var_24" select="Child Node1"
/>
<xsl:variable name="var_27" select="Child Node2"
/>

<!-- Variable to store the posittion of each
ParentGroup nodes -->
<xsl:variable name="parentGroup"> 
  <xsl:for-each select="ParentGroup">
    <parentgroup>
    <xsl:attribute name="id"
select="generate-id()"/>
    <xsl:attribute name="pos"
select="position()"/>
    </parentgroup>
  </xsl:for-each>
</xsl:variable>

  <xsl:for-each select="$var_21[count(. |
key('PRI_CUST', .)[1]) = 1]">
  <PRIMARY CUSTOMER>
     <xsl:variable name="priId" select="." />
     <xsl:variable name="p"
select="key('parentGroups', generate-id())/@pos"
/>
     <PRI_HEADER><xsl:value-of select="$p"/>
          <xsl:value-of select="$var_27[$p]"/>
     </PBU_HEADER>
     <PRIMARY_CUST_DESC>
        <xsl:value-of select="$var_24[$p]"/>
        <xsl:text> </xsl:text>
        <xsl:value-of select="$priId"/>
     </PRIMARY_CUST_DESC>

     <SECONDARY CUSTOMER> 
      <xsl:for-each select= SECONDARY CUSTOMER....
      ....group &.Do processing for Sec customers
     </SECONDARY CUSTOMER> 

    </End of for loop for Primary cusotmer>
    </PRIMARY CUSTOMER>
</CUSTOMERS>
</TRANS_OUTPUT>


In the above XSL..I get the value of $p undefined 

<xsl:variable name="p" select="key('parentGroups',
generate-id())/@pos" />

So when I access $var_27[$p] and $var_24[$p] ..I
get
nothing.

     <PRI_HEADER><xsl:value-of select="$p"/>
          <xsl:value-of select="$var_27[$p]"/>
     </PBU_HEADER>
     <PRIMARY_CUST_DESC>
        <xsl:value-of select="$var_24[$p]"/>
        <xsl:text> </xsl:text>
        <xsl:value-of select="$priId"/>
     </PRIMARY_CUST_DESC>


Can someone please let me know what has gone
wrong.




          


___________________________________________________________


=== message truncated === 

=====
regards,
Bhupendra.

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

--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: 
<mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--




--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--



<Prev in Thread] Current Thread [Next in Thread>