Try
<xsl:template match="DInfo">
<xsl:for-each select="//TInfo">
<xsl:variable name="name" select="@name"/>
<xsl:if test="not(preceding::TInfo[(_at_)name=$name])">
<xsl:call-template name="ShowTInfo"/>
</xsl:if>
</xsl:for-each>
</xsl:template>
HTH,
Ken Ross
Ph: +61 7 32359370
Mob: +61 (0)419 772299
Email: Ken(_dot_)Ross(_at_)iie(_dot_)qld(_dot_)gov(_dot_)au
-----Original Message-----
From: Sandeep_Karandikar(_at_)Dell(_dot_)com
[mailto:Sandeep_Karandikar(_at_)Dell(_dot_)com]
Sent: Tuesday, 21 January 2003 6:07 AM
To: xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com
Subject: RE: [xsl] XPath Problem.
Hi,
I think Wendell here did an excellent job of explaining me the steps that I
need to follow to get this going. So I wrote up a sample XML file and XSL
file and tried it using the XML editor and I don't think I am still doing it
right.
Here is the XML :
<?xml-stylesheet type="text/xsl" href="c:\Temp\test.xsl"?>
<RootNode>
<DInfo name="D1">
<TInfo name="t1"/>
<TInfo name="t2"/>
</DInfo>
<DInfo name="D2">
<DInfo name="D3">
<TInfo name="t5"/>
<TInfo name="t6"/>
</DInfo>
<DInfo name="D4">
<DInfo name="D5">
<TInfo name="t3"/>
<TInfo name="t4"/>
</DInfo>
<DInfo name="D6">
<TInfo name="t3"/>
<TInfo name="t4"/>
</DInfo>
</DInfo>
</DInfo>
</RootNode>
Here is the XSL:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format">
<xsl:template match="Root">
<xsl:apply-templates select="DInfo[(_at_)name='D2']"/>
</xsl:template>
<xsl:template match="DInfo">
<xsl:variable name="TInfo-descendants" select="//TInfo"/>
<xsl:for-each select="$TInfo-descendants">
<xsl:variable name="all-preceding-TInfos"
select="preceding::TInfo"/>
<!-- this variable collects all TInfos in
the document preceding this one -->
<xsl:variable name="preceding-TInfos"
select="$TInfo-descendants[count(.|$all-preceding-TInfos) =
count($all-preceding-TInfos)]"/>
<xsl:if test="@name =
$preceding-TInfos/@name">
<!-- the test will only allow a
TInfo through that has a name not on one of the preceding TInfos -->
<xsl:call-template
name="ShowTInfo"/>
</xsl:if>
</xsl:for-each>
</xsl:template>
<xsl:template name="ShowTInfo">
<xsl:value-of select="./@name"/>
</xsl:template>
</xsl:stylesheet>
The output that I am getting currently is : t3t4t3t4
The expected output is : t5t6t3t4 or more preferred t3t4t5t6
Can some one englighten me as to where am I am going wrong ?
Really Appreciate your help...
-Sandeep.
-----Original Message-----
From: Wendell Piez [mailto:wapiez(_at_)mulberrytech(_dot_)com]
Sent: Wednesday, January 08, 2003 3:16 PM
To: xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com
Subject: Re: [xsl] XPath Problem.
Hi Sandeep,
At 02:51 PM 1/8/2003, you wrote:
<RootNode>
<DInfo name="D1">
<TInfo name="t1"></T1>
<TInfo name="t2"></T2>
</DInfo>
<DInfo name="D2">
<DInfo name="D3">
<TInfo name="t1"></T1>
<TInfo name="t2"></T2>
</DInfo>
<DInfo name="D4">
<DInfo name="D5">
<TInfo name="t3"></T1>
<TInfo name="t4"></T2>
</DInfo>
<DInfo name="D6">
<TInfo name="t3"></T1>
<TInfo name="t4"></T2>
</DInfo>
</DInfo>
</DInfo>
</RootNode>
Required Output:-
<xsl:key name="TInfo-Key-By-Name" match="TInfo" use="@name"/>
<xsl:for-each
select="TInfo[count(.|key('TInfo-Key-By-Name',@name)[1]) = 1]">
<xsl:call-template name="ShowTInfo">
</xsl:for-each>
1. So when I have the RootNode Selected this works correctly and displays
me
t1, t2, t3 , t4 only once.
2. When I am on <DInfo name="D2"> I need to display t1, t2, t3, t4. However
only t3 and t4 get displayed since it thinks that t1 and t2 have already
been displayed.
Well, not exactly. Only t3 and t4 get displayed since it thinks (correctly)
that those are its only descendants that pass the test you have given,
which checks whether a TInfo is the first with its name value in the
document. In your example, inside DInfo D2, this is the case only for the
TInfo children of DInfo D5, not those of DInfo D3.
Keys are useful for deduplicating globally (i.e. within the entire
document), but in order to do local de-duplication, you have to think
harder. Your condition is apparently not to check a node's name value
globally (assuring it's the first in the document), but rather only among
the descendants of a particular node. This means comparing the value of its
name not to all the TInfo elements, but only those inside a particular
descendant ... which is a harder set to select.
Not impossible, however. Here's a template that matches a DInfo and gives
back only those TInfo descendants that are first within it:
<xsl:template match="DInfo">
<xsl:variable name="TInfo-descendants" select=".//TInfo"/>
<!-- this variable holds all the TInfo elements in our scope:
we'll need it later -->
<xsl:for-each select="$TInfo-descendants">
<!-- now we go process each of our TInfo descendants -->
<xsl:variable name="all-preceding-TInfos"
select="preceding::TInfo"/>
<!-- this variable collects all TInfos in the document preceding this
one -->
<xsl:variable name="preceding-TInfos"
select="$TInfo-descendants[count(.|$all-preceding-TInfos) =
count($all-preceding-TInfos)]"/>
<!-- this variable declaration uses an XPath idiom to get an
intersection between
the two sets of TInfos, resulting in all the TInfo elements in
scope that
precede this one -->
<xsl:if test="@name = $preceding-TInfos/@name">
<!-- the test will only allow a TInfo through that has a name not on
one of
the preceding TInfos -->
<xsl:call-template name="ShowTInfo">
</xsl:if>
</xsl:for-each>
</xsl:template>
Note this approach is liable to be fairly costly over large documents,
since it has to use the preceding:: axis to find nodes to check against.
Cheers,
Wendell
======================================================================
Wendell Piez
mailto:wapiez(_at_)mulberrytech(_dot_)com
Mulberry Technologies, Inc. http://www.mulberrytech.com
17 West Jefferson Street Direct Phone: 301/315-9635
Suite 207 Phone: 301/315-9631
Rockville, MD 20850 Fax: 301/315-8285
----------------------------------------------------------------------
Mulberry Technologies: A Consultancy Specializing in SGML and XML
======================================================================
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
IMPORTANT: This email (including any attachments) may contain confidential,
private or legally privileged information and may be protected by copyright.
You may
only use it if you are the person(s) it was intended to be sent to and if you
use it in an
authorised way. No one is allowed to use, review, alter, transmit, disclose,
distribute,
print or copy this e-mail without appropriate authority.
If this e-mail was not intended for you and was sent to you by mistake, please
telephone or e-mail me immediately, destroy any hard copies of this e-mail and
delete
it and any copies of it from your computer system. Any legal privilege and
confidentiality attached to this e-mail is not waived or destroyed by that
mistake.
It is your responsibility to ensure that this e-mail does not contain and is
not affected
by computer viruses, defects or interference by third parties or replication
problems
(including incompatibility with your computer system).
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list