RE: [xsl] Eliminating duplicate nodes

Subject: RE: [xsl] Eliminating duplicate nodes
From: "Mac Martine" <pub@xxxxxxxxxxxxxxxx>
Date: Mon, 14 Oct 2002 11:11:16 -0700
Thanks for the help. I thought it made perfect sense, but I'm still have
a couple issues. I have tried to give a simpler example that maybe you
could help me with...

I know this xml document structure doesn't make much sense, but I just
made it this way to show what I am trying to do. So, I want to display
the content of all nodes which have a unique id.
So, in the example

<records>
	<contact id="0001">
		<title id="mr">Mr</title>
		<forename id="john">John</forename>
		<surname id="smith">Smith</surname>
	</contact>
	<contact id="0001">
		<title id="othermr">Mr</title>
		<forename id="otherjohn">John</forename>
		<surname id="othersmith">Smith</surname>
	</contact>
	<contact id="0002">
		<title id="dr">Dr</title>
		<forename id="amy">Amy</forename>
		<surname id="jones">Jones</surname>
	</contact>
	<contact id="0003">
		<title id="dr">Dr</title>
		<forename id="amy">Amy</forename>
		<surname id="jones">Jones</surname>
	</contact>
</records>

...this would display:

Smith,
John (Mr)

Smith,
John (Mr)

Jones,
Amy (Dr)

Notice that although the first 2 'contact' nodes have the same id, I
want to traverse inside them.

Here is what I'm using now, but it doesn't do what I want:

<?xml version="1.0" encoding="ISO-8859-1"?>
 
<xsl:stylesheet version='1.0'
xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>

<xsl:key name="contacts-by-surname" match="*" use="@id" />

<xsl:template match="*">
	<xsl:for-each select="*[generate-id() =
generate-id(key('contacts-by-surname', @id))]">
		
		<xsl:value-of select="surname" />,<br />
		<xsl:value-of select="forename" /> 
		(<xsl:value-of select="title" />)<br /><br />
	
	</xsl:for-each>
</xsl:template>

</xsl:stylesheet>

Thanks so much!
-Mac









-----Original Message-----
From: owner-xsl-list@xxxxxxxxxxxxxxxxxxxxxx
[mailto:owner-xsl-list@xxxxxxxxxxxxxxxxxxxxxx] On Behalf Of Joerg
Heinicke
Sent: Sunday, October 13, 2002 1:03 PM
To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
Subject: Re: [xsl] Eliminating duplicate nodes

I don't see any grouping code. But here is an example:

Add this <xsl:key/> as child of <xsl:stylesheet/> to your XML document:
<xsl:key name="elements" match="*" use="concat(name(), '::', @id)"/>

Change all your <xsl:apply-templates/> to the following:

<xsl:apply-templates select="*[generate-id() = 
generate-id(key('elements', concat(name(), '::', @id)))]"/>

Maybe you don't need the name() in the grouping condition. It's for 
differing between <element1 id="foo"/> and <element2 id="foo"/>. If 
these two elements should count as "duplicate" change
"concat(name(), '::', @id)"    simply to   "@id".

Furthermore you have to add some special handling to these 
<xsl:apply-templates/> for elements without any @id. Maybe they should 
be processed in every case. Then simply change it to:

<xsl:apply-templates select="*[not(@id)] | *[generate-id() = 
generate-id(key('elements', concat(name(), '::', @id)))]"/>

And what's with text nodes? Maybe a third change:

<xsl:apply-templates select="text() | *[not(@id)] | *[generate-id() = 
generate-id(key('elements', concat(name(), '::', @id)))]"/>


 > 		<xsl:for-each select=".">
 > 				<xsl:apply-templates  />	
 > 		</xsl:for-each>

That's not meaningful. Change it simply to <xsl:apply-templates/>. The 
<xsl:for-each/> iterates over all current nodes - which can only be one,

as the name says the currently processed node.

Regards,

Joerg


Mac Martine wrote:
> 
> Ok, thanks.
> 
> I consider any 2 nodes with the same id to be duplicates.
> ...and actually, I don't' use call-template just apply-template
> 
> 
> So, here's my code....
> 
> Thanks again,
> mac
> 
> <xsl:stylesheet version='1.0'
> xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>
> 
> <xsl:template match="/">
> 	<body bgcolor="black" text="white">
> 	<form name="creations" method="get"
> action="writeTestRunOptions.asp">
> 	<table>
> 		<xsl:for-each select=".">
> 				<xsl:apply-templates  />	
> 		</xsl:for-each>
> 	</table>
> 	</form>
> 	</body>
> </xsl:template>
> 
> <xsl:template match="panel|comboBox">
> 	<tr>
> 	<td>
> 		<xsl:apply-templates  />
> 	</td>
> 	</tr>
> </xsl:template>
> 
> <xsl:template match="checkBox|button|radioButton">
> 	<tr>
> 	<td>
> 		<xsl:apply-templates  />
> 		<input type="checkbox" name="{@id}" value="{node()}"/>
> 	</td>
> 	</tr>
> </xsl:template>
> 
> <xsl:template match="label">
> 	<tr>
> 		<td bgcolor="darkred">
> 			<font color="red">
> 				<xsl:apply-templates  />
> 				<xsl:value-of select="@node" />
> 			</font>
> 		</td>
> 	</tr>
> </xsl:template>
> 
> <xsl:template match="lineEdit">
> 	<tr>
> 	<td>
> 		 [created automatically]
> 	</td>
> 	</tr>
> </xsl:template>
> 
> <xsl:template match="item">
> 	<xsl:choose>
> 		<xsl:when test="position() = 1">
> 			<input type="checkbox" value="{node()}"
> name="{../@id}" checked="true"/>
> 		</xsl:when>
> 		<xsl:otherwise>
> 			<input type="checkbox" value="{node()}"
> name="{../@id}"/>
> 		</xsl:otherwise>
> 	</xsl:choose>
> 	<xsl:value-of select="node()" />
> 	<br />
> </xsl:template>
> 
> </xsl:stylesheet>
> 
> ===============================================================
> 
> <main>
> 
>   <dialog id="pw">
>     <label id="pw.titleBar"></label>
>       <panel id="pw.publish">
>         <group id="pw.publish.frame">
>           <panel id="pw.publish.group">
>             <label id="pw.publish.lbl">Publish options:</label>
>             <button id="pw.publish.print">Print</button>
>             <button id="pw.publish.email">E-mail</button>
>           </panel>
>         </group>
>         <group id="pw.summmary.frame">
>           <panel id="pw.summary.group">
>             <label id="pw.projectName.lbl">Name:</label>
>             <lineEdit id="pw.projectName"></lineEdit>
>             <checkBox id="pw.usetitleforname.cb">Use Title for
> Name</checkBox>
>             <label id="pw.summary.lbl"></label>
>             <label id="pw.graphic"></label>
>           </panel>
>         </group>
>       </panel>
>       <panel id="pw.template">
>         <group id="pw.title.frame">
>           <panel id="pw.title.group">
>             <checkBox id="pw.title.cb"></checkBox>
>             <label id="pw.title.lbl">Title:</label>
>             <lineEdit id="pw.title"></lineEdit>
>           </panel>
>         </group>
>         <group id="pw.pages.frame">
>           <panel id="pw.pages.group">
>             <label id="pw.pages.lbl">Photos Per Page:</label>
>             <comboBox id="pw.pages">
>               <item>1</item>
>               <item>2</item>
>               <item>3</item>
>               <item>4</item>
>               <item>Sequence: 1, 2, repeat</item>
>               <item>Sequence: 1, 3, 2, repeat</item>
>               <item>Sequence: 1, 3, 2, 4, repeat</item>
>             </comboBox>
>             <checkBox id="pw.captions">Include Captions</checkBox>
>             <checkBox id="pw.pageNums">Include Page Numbers</checkBox>
>             <label id="pw.header.lbl">Header:</label>
>             <lineEdit id="pw.header"></lineEdit>
>             <label id="pw.footer.lbl">Footer:</label>
>             <lineEdit id="pw.footer"></lineEdit>
>           </panel>
>         </group>
>       </panel>
>   </dialog>
> 
>   <dialog id="pw">
>     <label id="pw.titleBar"></label>
>       <panel id="pw.publish">
>         <group id="pw.publish.frame">
>           <panel id="pw.publish.group">
>             <label id="pw.publish.lbl">Publish Options:</label>
>             <button id="pw.publish.print">Print</button>
>             <button id="pw.publish.email">E-mail</button>
>           </panel>
>         </group>
>         <group id="pw.summmary.frame">
>           <panel id="pw.summary.group">
>             <label id="pw.projectName.lbl">Name:</label>
>             <lineEdit id="pw.projectName"></lineEdit>
>             <checkBox id="pw.usetitleforname.cb">Use Title for
> Name</checkBox>
>             <label id="pw.summary.lbl"></label>
>             <label id="pw.graphic"></label>
>           </panel>
>         </group>
>       </panel>
>       <panel id="pw.template">
>         <group id="pw.title.frame">
>           <panel id="pw.title.group">
>             <checkBox id="pw.title.cb"></checkBox>
>             <label id="pw.title.lbl">Title:</label>
>             <lineEdit id="pw.title"></lineEdit>
>           </panel>
>         </group>
>         <group id="pw.pages.frame">
>           <panel id="pw.pages.group">
>             <label id="pw.pages.lbl">Photos Per Page:</label>
>             <comboBox id="pw.pages">
>               <item>1</item>
>               <item>2</item>
>               <item>3</item>
>               <item>Sequence: 1, 2, repeat</item>
>               <item>Sequence: 1, 3, 2, repeat</item>
>             </comboBox>
>             <checkBox id="pw.captions">Include Captions</checkBox>
>           </panel>
>         </group>
>         <group id="pw.presentation.frame">
>           <panel id="pw.presentation.group">
>             <checkBox id="pw.repeat">Repeat Slideshow</checkBox>
>             <checkBox id="pw.showControls">Include Play
> Controls</checkBox>
>             <checkBox id="pw.allowResize">Allow to Resize</checkBox>
>             <label id="pw.transition.lbl">Transition:</label>
>             <comboBox id="pw.transition">
>               <item>None</item>
>               <item>1</item>
>               <item>2</item>
>               <item>3</item>
>               <item>4</item>
>             </comboBox>
>             <label id="pw.duration.lbl">Time</label>
>             <comboBox id="pw.duration">
>               <item>2 sec</item>
>               <item>4 sec</item>
>               <item>10 sec</item>
>             </comboBox>
>             <label id="pw.music.lbl">Background Music:</label>
>             <comboBox id="pw.music">
>               <item>None</item>
>               <item>A_fool_and_the_thing_h.mp3</item>
>             </comboBox>
>             <button id="pw.music.browse">Browse</button>
>             <checkBox id="pw.audioCaptions">Play Audio
> Captions</checkBox>
>           </panel>
>         </group>
>       </panel>
>   </dialog>
>   </main>
> 
> 
> 
> 
> 
> 
> -----Original Message-----
> From: owner-xsl-list@xxxxxxxxxxxxxxxxxxxxxx
> [mailto:owner-xsl-list@xxxxxxxxxxxxxxxxxxxxxx] On Behalf Of Joerg
> Heinicke
> Sent: Saturday, October 12, 2002 3:00 PM
> To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
> Subject: Re: [xsl] Eliminating duplicate nodes
> 
> Hi Mac,
> 
> you must tell us, how you define "duplicate nodes". In your XML the 
> following snippet is obviously duplicate:
> 
>  >       <panel id="selection">
>  >         <label id="selection">Select the template type:</label>
>  >         <button id="download">Download New Templates</button>
>  >         <label id="detail"></label>
>  >       </panel>
> 
> But what is when one of the text nodes is different or the button has 
> another id, but the rest is the same? Tell us the rules for identity.
> 
> Another question is what you are doing with <xsl:call-template/>. This

> often breaks normal XML tree processing.
> 
> Did you have already a look at 
> http://www.jenitennison.com/xslt/grouping/muenchian.xml? Can you post
a 
> bit of your non-working code?
> 
> Regards,
> 
> Joerg
> 
> Mac Martine wrote:
> 
>>Hi-
>> I am trying creating an HTML page from XML/XSL.
>>I want to eliminate duplicate nodes, and it seems like there are 2
> 
> ways
> 
>>to do this: using variables, and using keys. But I haven't gotten
> 
> either
> 
>>to work yet.
>>Could someone recommend which method would be better, and maybe help
> 
> get
> 
>>me started on the right path?
>>
>>Below is a little snippet of my xml:
>>I use <call-template> when I hit nodes of a certain name
>>
>>Thanks-
>> Mac
>>
>><desktop>
>>	  <label id="titleBar"></label>
>>      <panel id="selection">
>>        <label id="selection">Select the template type:</label>
>>        <button id="download">Download New Templates</button>
>>        <label id="detail"></label>
>>      </panel>
>>      <panel id="style">
>>        <label id="style">Choose your Slideshow style:</label>
>>        <label id="preview"></label>
>>      </panel>
>>
>>	 <label id="titleBar"></label>
>>      <panel id="selection">
>>        <label id="selection">Select the template type:</label>
>>        <button id="download">Download New Templates</button>
>>        <label id="detail"></label>
>>      </panel>
>>      <panel id="style">
>>        <label id="style">Choose your Slideshow style:</label>
>>        <label id="preview"></label>
>>      </panel>
>></desktop>
> 
> 
> 
>  XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
> 
> 
> 
>  XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
> 
> 



 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list



 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list


Current Thread