Jump to content

Distinct XML


andreathedove
 Share

Recommended Posts

Hello all,and I thank you to help me.I have this XML (Code simplified):

<?xml version="1.0" encoding="UTF-8" ?> - <products>- <product>  <TDProductId>137525899</TDProductId>   <name>Corso MS Access (Mod. Easy)</name>   <description>Impara a creare e gestire database in maniera semplice e veloce. E' prevista la consultazione del corso, l'accesso all'area download, al blocco appunti ed al forum di assistenza (in sola lettura) per 30 giorni.</description>   <imageUrl>http://www.mrwcorsi.it/immagini/icone/21.gif</imageUrl>   <productUrl>http://pdt.tradedoubler.com/click?a(1228273)p(57404)prod(137525899)ttid(3)</productUrl>   <price>30.00</price>   <currency>EUR</currency> - <TDCategories>- <TDCategory>  <id>362</id>   <name>E learning</name>   <merchantName>Corsi</merchantName>   </TDCategory>  </TDCategories>  <fields />   </product>- <product>  <TDProductId>137525929</TDProductId>   <name>Corso MS Access (Mod. Tutor)</name>   <description>Impara a creare e gestire database in maniera semplice e veloce. E' prevista la consultazione del corso, l'accesso all'area download, al blocco appunti, ai quiz di autovalutazione e l'assistenza per tutor 30 giorni.</description>   <imageUrl>http://www.mrwcorsi.it/immagini/icone/21.gif</imageUrl>   <productUrl>http://pdt.tradedoubler.com/click?a(1228273)p(57404)prod(137525929)ttid(3)</productUrl>   <price>60.00</price>   <currency>EUR</currency> - <TDCategories>- <TDCategory>  <id>362</id>   <name>E learning</name>   <merchantName>Corsi</merchantName>   </TDCategory>  </TDCategories>  <fields />   </product>- <product>  <TDProductId>137526017</TDProductId>   <name>Corso MySQL (Mod. Tutor)</name>   <description>Gestione del database open-source. E' prevista la consultazione del corso, l'accesso all'area download, al blocco appunti, ai quiz di autovalutazione e l'assistenza per tutor 30 giorni.</description>   <imageUrl>http://www.mrwcorsi.it/immagini/icone/16.gif</imageUrl>   <productUrl>http://pdt.tradedoubler.com/click?a(1228273)p(57404)prod(137526017)ttid(3)</productUrl>   <price>100.00</price>   <currency>EUR</currency> - <TDCategories>- <TDCategory>  <id>362</id>   <name>E learning</name>   <merchantName>Corsi</merchantName>   </TDCategory>  </TDCategories>  <fields />   </product>- <product>  <TDProductId>137526027</TDProductId>   <name>Corso MySQL (Mod. Certificate)</name>   <description>Gestione del database open-source. E' prevista la consultazione del corso, l'accesso all'area download, al blocco appunti, ai quiz di autovalutazione e l'assistenza per tutor 60 giorni. Al termine del corso riceverete l'attestato finale di partecipazione.</description>   <imageUrl>http://www.mrwcorsi.it/immagini/icone/16.gif</imageUrl>   <productUrl>http://pdt.tradedoubler.com/click?a(1228273)p(57404)prod(137526027)ttid(3)</productUrl>   <price>120.00</price>   <currency>EUR</currency> - <TDCategories>- <TDCategory>  <id>362</id>   <name>E learning</name>   <merchantName>Corsi</merchantName>   </TDCategory>  </TDCategories>  <fields />   </product></products>

and the XSL:

<?xml version="1.0"?><xsl:stylesheet version="1.0"    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">    <xsl:output method="html" />        <xsl:template match="products"><a class="titoli" href='/'>Home</a> | <a class="titoli" href='/gamezone'>GameZone</a> | <b>Giochi professionali</b><div id="dir">			<strong>Categorie GameZone:</strong>				<ul>	<xsl:for-each select="/products/product"><xsl:sort select="name" data-type="text" order="ascending" /><li><xsl:value-of select="name"/> - <a class="titoli" href="name"><b><xsl:value-of select="substring-before(name,'(')"/></b></a></li><br /></xsl:for-each></ul></div></xsl:template></xsl:stylesheet>

To transform all I use ASP, this is the code:

<?xml version="1.0" encoding="UTF-8" ?> <%@ Language="VBScript" %> <%page = "Giochi AllinOneNet.it"%><!--#INCLUDE FILE="header.asp" --><div id="content"><%    ' Dichiaro le variabili che mi servono    Dim database_z, style_z    ' Setto due oggetti XMLDOM, uno per il file XML    ' ed un secondo per il file di stile dinamico XSLT    Set database_z = Server.CreateObject("Microsoft.XMLDOM")    Set style_z = Server.CreateObject("Microsoft.XMLDOM")    ' Setto i due oggetti come sincroni    database_z.async = false    database_z.setProperty "ServerHTTPRequest", True    database_z.validateOnParse =false    database_z.preserveWhiteSpace = false    style_z.async = False    ' Carico i file XML ed XSLT    database_z.load("http://pf.tradedoubler.com/pf/pf?a=1228273&categoryId=361&recurse=true&programs=57404&maxResults=100&firstResult=0")    style_z.load Server.MapPath("cat.xsl")    ' Nel corpo della pagina effettuo la trasformazione...%><%=database_z.transformNode(style_z)%><%    ' Un po di pulizia...    Set database_z = Nothing    Set style_z = Nothing%></div><!--#INCLUDE FILE="sinistro.asp" --><!--#INCLUDE FILE="footer.asp" -->

The resul with all XML file is here:http://www.allinonenet.it/webmasterzone/ta...nuali/index.aspSo, I would like to build a directory used the tag "name":for example with the list XML upCorso MS AccessCorso MySQLWith the FUNCTIONSsubstring-before(name,'(')I have fromCorso MySQL (Mod. Tutor)toCorso MySQL But the problem is How I can distinct all the XML (with [not(preceding-simbling)])to obtain The Category list?Thanks,Andrea

Link to comment
Share on other sites

You seem a little vague with the description of the actual problem, but it again seems to me you're just begging for the set:distict() function/template.What exactly is the output you want? I can see your current, but try to write down a sample code of what should really happen.

Link to comment
Share on other sites

You seem a little vague with the description of the actual problem, but it again seems to me you're just begging for the set:distict() function/template.What exactly is the output you want? I can see your current, but try to write down a sample code of what should really happen.
Hello boen_robot,can you help me to implement my XSL with set:distict() ?Thanks,Andrea
Link to comment
Share on other sites

Hello boen_robot,can you help me to implement my XSL with set:distict() ?Thanks,Andrea
The page I gave you a reference to pretty much says it all. The only additional one you may need is the How To page.In particular, download the set:distinct template and include/import it in your stylesheet with the xsl:include/xsl:import element. Also, add a namespace declaration at the top of your document for the "set" prefix. The namespace URI is "http://exslt.org/sets". So, as by the example in the "set" category, the top of your stylesheet may become something like:
<xsl:stylesheet version="1.0"				xmlns:xsl="http://www.w3.org/1999/XSL/Transform"				xmlns:set="http://exslt.org/sets"				extension-element-prefixes="set"><xsl:import href="set.xsl" />

Link to comment
Share on other sites

The page I gave you a reference to pretty much says it all. The only additional one you may need is the How To page.In particular, download the set:distinct template and include/import it in your stylesheet with the xsl:include/xsl:import element. Also, add a namespace declaration at the top of your document for the "set" prefix. The namespace URI is "http://exslt.org/sets". So, as by the example in the "set" category, the top of your stylesheet may become something like:
<?xml version="1.0"?><xsl:stylesheet version="1.0"                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"                xmlns:set="http://exslt.org/sets"                extension-element-prefixes="set"><xsl:import href="set.distinct.function.xsl" /><xsl:output method="html" />        <xsl:template match="products"><a class="titoli" href='/'>Home</a> | <a class="titoli" href='/gamezone'>GameZone</a> | <b>Giochi professionali</b><div id="dir">			<strong>Categorie GameZone:</strong>				<ul>	<xsl:for-each select="set:distinct(/products/product)"><xsl:sort select="name" data-type="text" order="ascending" /><li><xsl:value-of select="name"/> - <a class="titoli" href="name"><b><xsl:value-of select="substring-before(name,'(')"/></b></a></li><br /></xsl:for-each></ul></div></xsl:template></xsl:stylesheet>

and the result ishttp://www.allinonenet.it/webmasterzone/ta...nuali/index.aspWhy?Thanks,Andrea

Link to comment
Share on other sites

What you just imported was the template, not the function. The funciton only works with the XSLT processors listed on the set:distinct page, or at least the ones that support the <exsl:function/> element, as that's the only way the set:distinct() function can be plugged in to non-supporting processors.For the rest, if you want to call that template (forgetting about the function), you need to use

<xsl:call-template name="set:distinct"><xsl:with-param name="nodes" select="/products/product" /></xsl:template>

How exactly are you going to make your stylesheet use that result, I'm not sure... perhaps by storing this value in a variable and then loop thru it like

<xsl:variable name="set:distinct"><xsl:call-template name="set:distinct"><xsl:with-param name="nodes" select="/products/product" /></xsl:template></xsl:variable><xsl:for-each select="set:distinct">...</xsl:for-each>

but I have no idea if that would work honestly.

Link to comment
Share on other sites

What you just imported was the template, not the function. The funciton only works with the XSLT processors listed on the set:distinct page, or at least the ones that support the <exsl:function/> element, as that's the only way the set:distinct() function can be plugged in to non-supporting processors.For the rest, if you want to call that template (forgetting about the function), you need to use
<xsl:stylesheet version="1.0"                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"                xmlns:set="http://exslt.org/sets"                extension-element-prefixes="set"><xsl:import href="set.distinct.function.xsl" /><xsl:output method="html" /><xsl:variable name="set:distinct"><xsl:call-template name="set:distinct"><xsl:with-param name="nodes" select="/products/product" /></xsl:call-template></xsl:variable>     <xsl:template name="set:distinct" match="/"><xsl:with-param name="nodes" select="/products/product" /><a class="titoli" href='/'>Home</a> | <a class="titoli" href='/gamezone'>GameZone</a> | <b>Giochi professionali</b><div id="dir"><strong>Categorie GameZone:</strong><ul><xsl:for-each select="set:distinct"><xsl:sort select="name" data-type="text" order="ascending" /><li><xsl:value-of select="name"/> - <a class="titoli" href="name"><b><xsl:value-of select="substring-before(name,'(')"/></b></a></li><br /></xsl:for-each></ul></div></xsl:template></xsl:stylesheet>

AND THE RESULT:http://www.allinonenet.it/webmasterzone/tab_manuali/Why? :-(Thanks,Andrea

Link to comment
Share on other sites

Opps. My bad. I forgot a "$" before the variable reference. It's
<xsl:stylesheet version="1.0"                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"                		xmlns:set="http://exslt.org/sets"                extension-element-prefixes="set">		<xsl:import href="set.distinct.function.xsl" />		<xsl:output method="html" />		<xsl:variable name="set:distinct">		<xsl:call-template name="set:distinct">		<xsl:with-param name="nodes" select="/products/product" />		</xsl:call-template>		</xsl:variable>     		<xsl:template name="set:distinct" match="/">		<xsl:with-param name="nodes" select="/products/product" />		<a class="titoli" href='/'>Home</a> | 		<a class="titoli" href='/gamezone'>GameZone</a> | 		<b>Giochi professionali</b>		<div id="dir">		<strong>Categorie GameZone:</strong>		<ul><xsl:for-each select="$set:distinct">		<xsl:sort select="name" data-type="text" order="ascending" />		<li><xsl:value-of select="name"/> - 		<a class="titoli" href="name"><b><xsl:value-of select="substring-before(name,'(')"/></b></a></li>		<br /></xsl:for-each></ul></div>		</xsl:template>		</xsl:stylesheet>

The result page:http://www.allinonenet.it/webmasterzone/tab_manuali/thanks,Andrea

Link to comment
Share on other sites

Think about how things are processed just for a second... you have a template that implements set:distinct and you call that template within another template to emulate the behaviour of the function. The variable is needed within the template so that you can store the result and then loop thru it. Oh, for god's sake:

<?xml version="1.0"?><xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:set="http://exslt.org/sets" extension-element-prefixes="set">	<xsl:import href="set.distinct.function.xsl" />	<xsl:output method="html" />			<xsl:template match="products">		<a class="titoli" href='/'>Home</a> | <a class="titoli" href='/gamezone'>GameZone</a> | <b>Giochi professionali</b>		<div id="dir">			<strong>Categorie GameZone:</strong>			<ul>				<xsl:variable name="set:distinct">					<xsl:call-template name="set:distinct">						<xsl:with-param name="node-set" select="/products/product"/>					</xsl:call-template>				</xsl:variable>				<xsl:for-each select="$set:distinct">					<xsl:sort select="name" data-type="text" order="ascending" />					<li>						<xsl:value-of select="name"/> - <a class="titoli" href="name"><b><xsl:value-of select="substring-before(name,'(')"/></b></a>					</li>					<br />				</xsl:for-each>			</ul>		</div>	</xsl:template></xsl:stylesheet>

If that doesn't work either, then you'll also need the exsl:node-set extension, which is impossible to plug-in with a template. You MUST have a processor that supports that, an XSLT processor that supports the exsl:function element or an XSLT 2.0 processor.

Link to comment
Share on other sites

Think about how things are processed just for a second... you have a template that implements set:distinct and you call that template within another template to emulate the behaviour of the function. The variable is needed within the template so that you can store the result and then loop thru it. Oh, for god's sake:
<?xml version="1.0"?><xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:set="http://exslt.org/sets" extension-element-prefixes="set">	<xsl:import href="set.distinct.function.xsl" />	<xsl:output method="html" />			<xsl:template match="products">		<a class="titoli" href='/'>Home</a> | <a class="titoli" href='/gamezone'>GameZone</a> | <b>Giochi professionali</b>		<div id="dir">			<strong>Categorie GameZone:</strong>			<ul>				<xsl:variable name="set:distinct">					<xsl:call-template name="set:distinct">						<xsl:with-param name="node-set" select="/products/product"/>					</xsl:call-template>				</xsl:variable>				<xsl:for-each select="$set:distinct">					<xsl:sort select="name" data-type="text" order="ascending" />					<li>						<xsl:value-of select="name"/> - <a class="titoli" href="name"><b><xsl:value-of select="substring-before(name,'(')"/></b></a>					</li>					<br />				</xsl:for-each>			</ul>		</div>	</xsl:template></xsl:stylesheet>

If that doesn't work either, then you'll also need the exsl:node-set extension, which is impossible to plug-in with a template. You MUST have a processor that supports that, an XSLT processor that supports the exsl:function element or an XSLT 2.0 processor.

Hello,this is the resulthttp://www.allinonenet.it/webmasterzone/tab_manuali/Thanks,Andrea
Link to comment
Share on other sites

I'm not sure that the result you posted is what you are looking for, nor am I sure what you are looking for, but it seems that you are not getting it. I have made an assumption that you are trying to group items by the TDCategory/name node and then list all products by name that fall within that category. Please try the following XSLT and see if it does what you are looking for. If I have misunderstood your intentions. please restate them.

<?xml version="1.0"?><xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"><xsl:output method="html" /><xsl:key name="cat" 	match="TDCategory"	 use="name"/><xsl:template match="products"> 	<xsl:for-each select="//product//TDCategory[count(. | key('cat', name)[1]) = 1]">		<xsl:variable name="cat" select="name"/>		<h3><xsl:value-of select="name"/></h3>		<xsl:for-each select="//product[//TDCategory[name=$cat]]">			<h4><xsl:value-of select="name"/></h4>		</xsl:for-each>		</xsl:for-each></xsl:template></xsl:stylesheet>

Link to comment
Share on other sites

I'm not sure that the result you posted is what you are looking for, nor am I sure what you are looking for, but it seems that you are not getting it. I have made an assumption that you are trying to group items by the TDCategory/name node and then list all products by name that fall within that category. Please try the following XSLT and see if it does what you are looking for. If I have misunderstood your intentions. please restate them.
<?xml version="1.0"?><xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"><xsl:output method="html" /><xsl:key name="cat" 	match="TDCategory"	 use="name"/><xsl:template match="products"> 	<xsl:for-each select="//product//TDCategory[count(. | key('cat', name)[1]) = 1]">		<xsl:variable name="cat" select="name"/>		<h3><xsl:value-of select="name"/></h3>		<xsl:for-each select="//product[//TDCategory[name=$cat]]">			<h4><xsl:value-of select="name"/></h4>		</xsl:for-each>		</xsl:for-each></xsl:template></xsl:stylesheet>

Hello aalbetski,I thanks you very much to help me.I would like witn "Name" to built a category:Corso MS Access Corso MySQLCorso SQL e Database ...and so on ...Thanks,Andrea
Link to comment
Share on other sites

lets try again

<?xml version="1.0"?><xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"><xsl:output method="html" /><xsl:key name="name" 	match="name"	 use="."/><xsl:template match="products"> 	<xsl:for-each select="//product/name[count(. | key('name', .)[1]) = 1]">			<h4><xsl:value-of select="."/></h4>	</xsl:for-each></xsl:template></xsl:stylesheet>

Link to comment
Share on other sites

lets try again
<?xml version="1.0"?><xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"><xsl:output method="html" /><xsl:key name="name" 	match="name"	 use="."/><xsl:template match="products"> 	<xsl:for-each select="//product/name[count(. | key('name', .)[1]) = 1]">			<h4><xsl:value-of select="."/></h4>	</xsl:for-each></xsl:template></xsl:stylesheet>

with your code the result is:http://www.allinonenet.it/webmasterzone/tab_manuali/So, with this functionssubstring-before(name, '(')I can have this:Corso MS Access Corso MS Access Corso MS Access Corso MS Access Corso MySQL Corso MySQL Corso MySQL Corso MySQL Corso SQL e Database Corso SQL e Database Corso SQL e Database Corso SQL e Database Corso ASP Base Corso ASP Base Corso ASP Base Corso ASP Base Corso ASP Completo Corso ASP Completo Corso ASP Completo Corso ASP CompletoSo, how can I have this distinct result:Corso MS Access Corso MySQL Corso ASP Base Corso ASP Completo ?Andrea
Link to comment
Share on other sites

I think I finally understand, try this:

<?xml version="1.0"?><xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"><xsl:output method="html" /><xsl:key name="name"	 match="name"	 use="substring-before(.,'(')"/><xsl:template match="products">	<xsl:for-each select="//product/name[count(. | key('name', substring-before(.,'('))[1]) = 1]">			<h4><xsl:value-of select="substring-before(.,'(')"/></h4>	</xsl:for-each></xsl:template></xsl:stylesheet>

Link to comment
Share on other sites

I think I finally understand, try this:
<?xml version="1.0"?><xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"><xsl:output method="html" /><xsl:key name="name"	 match="name"	 use="substring-before(.,'(')"/><xsl:template match="products">	<xsl:for-each select="//product/name[count(. | key('name', substring-before(.,'('))[1]) = 1]">			<h4><xsl:value-of select="substring-before(.,'(')"/></h4>	</xsl:for-each></xsl:template></xsl:stylesheet>

I thanks you very very very much, it work.Andrea
Link to comment
Share on other sites

add the IMG tag:

<?xml version="1.0"?><xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"><xsl:output method="html" /><xsl:key name="name"	 match="name"	 use="substring-before(.,'(')"/><xsl:template match="products">	<xsl:for-each select="//product/name[count(. | key('name', substring-before(.,'('))[1]) = 1]">			<img src="{../imageUrl}" />			<xsl:value-of select="substring-before(.,'(')"/>	</xsl:for-each></xsl:template></xsl:stylesheet>

I will leave the alignment and display up to you

Link to comment
Share on other sites

add the IMG tag:
<?xml version="1.0"?><xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"><xsl:output method="html" /><xsl:key name="name"	 match="name"	 use="substring-before(.,'(')"/><xsl:template match="products">	<xsl:for-each select="//product/name[count(. | key('name', substring-before(.,'('))[1]) = 1]">			<img src="{../imageUrl}" />			<xsl:value-of select="substring-before(.,'(')"/>	</xsl:for-each></xsl:template></xsl:stylesheet>

I will leave the alignment and display up to you

thanks very much again.Andrea
Link to comment
Share on other sites

Hello,In this line where is the error<xsl:for-each select="//products/product[substring-before(name,'(')=$category]">?Thanks,Andrea
Show the new XSLT. What I'm wondering in particular is what (if anything) forms the $category variable.
Link to comment
Share on other sites

Show the new XSLT. What I'm wondering in particular is what (if anything) forms the $category variable.
The code:
<?xml version="1.0" ?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">        <xsl:output method="html" encoding="iso-8859-1"/>    <xsl:param name="category"/>    <xsl:template match="/"><xsl:variable name="cat" select="//products/product/name"/><xsl:variable name="totale" select="count(//products/product[name=$category])"/>[ <xsl:value-of select="$totale"/> ]<br /><br /><br /><table><tr><xsl:for-each select="//products/product[name=$category]"><xsl:sort select="name" data-type="text" order="ascending" /><td><a href="game.asp?gameid={name}"><b><xsl:value-of select="name"/></b></a> <br /></td> <xsl:if test="position() mod 3 = 0">                        <!-- Blocco CDATA assieme a codice Javascript -->                        <script>                            <![CDATA[document.write("</tr><tr>");]]>                        </script>                        <!-- FINE Blocco CDATA assieme a codice Javascript -->                    </xsl:if>   </xsl:for-each></tr></table></xsl:template></xsl:stylesheet>

the string for the category:display.asp?cat=xxxThanks,Andrea

Link to comment
Share on other sites

When you pass a value to the parameter, the value can only be placed on a top level parameter like $category.However, when there's no value, you may get nothing. You should probably specify a default value to be sure.If you mean there's an error message, try to somehow get it and show it. It may point to a syntax error in the XSLT file, or an illegal construct (which I don't notice right now). I don't know how exactly do you get messages in ASP though. Hope aalbetski can show you that if you don't know either.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...