[XSL-LIST Mailing List Archive Home] [By Thread] [By Date]

RE: [xsl] XPath Problem.


Subject: RE: [xsl] XPath Problem.
From: "Ross Ken" <Ken.Ross@xxxxxxxxxxxxxx>
Date: Tue, 21 Jan 2003 07:46:21 +1000

Try

	<xsl:template match="DInfo">
		<xsl:for-each select="//TInfo">
			<xsl:variable name="name" select="@name"/>
			<xsl:if test="not(preceding::TInfo[@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.Ross@xxxxxxxxxxxxxx


-----Original Message-----
From: Sandeep_Karandikar@xxxxxxxx [mailto:Sandeep_Karandikar@xxxxxxxx]
Sent: Tuesday, 21 January 2003 6:07 AM
To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
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[@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@xxxxxxxxxxxxxxxx]
Sent: Wednesday, January 08, 2003 3:16 PM
To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
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@xxxxxxxxxxxxxxxx
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



Current Thread
Keywords