equentin
asked on
XSL cycle through alphabet
I want to display the alphabet, and where there is a matching entry in my XML, I want the letter to be a link (ie for letters ACDFSW). So for instance I have my XML doc:
<root><data><alphabet><cha r>A</char> </alphabet ><alphabet ><char>C</ char></alp habet><alp habet><cha r>D</char> </alphabet ><alphabet ><char>F</ char></alp habet><alp habet><cha r>S</char> </alphabet ><alphabet ><char>W</ char></alp habet></da ta></root>
How can I get my XSL to display each other letter?
Hope this is clear!
Ta,
eq
<root><data><alphabet><cha
How can I get my XSL to display each other letter?
Hope this is clear!
Ta,
eq
ASKER
Hmmm... Thanks for that - but being a bit of a novice at XSL, how do I get my char xml into your line:
<xsl:key match="char" name="chars" use="." />
The way I've been referring to my node sets before is to use
<xsl:for-each select="msxsl:node-set($pa geData)//c har/." > if that helps at all.
Sorry for any vagueness - it's all v confusing to me!
Ta,
eq
<xsl:key match="char" name="chars" use="." />
The way I've been referring to my node sets before is to use
<xsl:for-each select="msxsl:node-set($pa
Sorry for any vagueness - it's all v confusing to me!
Ta,
eq
Eq,
what does $pageData refer to?? Could you show the relevant parts of your XSLT??
rgds,
Conor.
what does $pageData refer to?? Could you show the relevant parts of your XSLT??
rgds,
Conor.
ASKER
I'm inheriting this project off someone else, so it may not have been written in the best way, and we're all a bit of novices in the XML/XSL arena, so apologies if it's a bit messy!
Ok, the XSL stylesheet is called from an ASP page that gets the XML out of SQL server and creates the XML. It's in the format of <root><data><alphabet><cha r>A</char> </alphabet >[etc]</ro ot>
ASP then applies the XML to a variable (pagedata) using loadData.documentElement. In the stylesheet we get the data out of this by using a command like <xsl:for-each select="msxsl:node-set($pa geData)//a lphabet/." >.
Hope this makes things clearer - appreciate it's a tad vague, so I've increased the points to 500.
Cheers,
eq
Ok, the XSL stylesheet is called from an ASP page that gets the XML out of SQL server and creates the XML. It's in the format of <root><data><alphabet><cha
ASP then applies the XML to a variable (pagedata) using loadData.documentElement. In the stylesheet we get the data out of this by using a command like <xsl:for-each select="msxsl:node-set($pa
Hope this makes things clearer - appreciate it's a tad vague, so I've increased the points to 500.
Cheers,
eq
Eq,
Since you are using the msxsl:nodeset element I assume the XML is inside a variable/parameter.
I have placed the XML data inside a param named "pageData".
As a matter of interest what is your stylesheet applied to?? And how is the variable pageData passed to the stylesheet??
<xsl:stylesheet version="1.0" exclude-result-prefixes="m sxsl"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-m icrosoft-c om:xslt">
<xsl:param name="pageData">
<root><data><alphabet><cha r>A</char> </alphabet ><alphabet ><char>C</ char></alp habet><alp habet><cha r>D</char> </alphabet >
<alphabet><char>F</char></ alphabet>< alphabet>< char>S</ch ar></alpha bet><alpha bet><char> W</char></ alphabet>< /data></ro ot>
</xsl:param>
<xsl:variable name="alphabet" select="'ABCDEFGHIJKLMNOPQ RSTUVWXYZ' " />
<xsl:key match="char" name="chars" use="." />
<xsl:template match="/">
<xsl:call-template name="process.alphabet">
<xsl:with-param name="letters" select="$alphabet" />
</xsl:call-template>
</xsl:template>
<xsl:template name="process.alphabet">
<xsl:param name="letters" select="''" />
<xsl:variable name="thisletter" select="substring($letters , 1, 1)" />
<xsl:if test="$letters != ''">
<xsl:for-each select="msxsl:node-set($pa geData)">
<xsl:choose>
<xsl:when test="key('chars', $thisletter)">
<a href="{$thisletter}.html"> <xsl:value -of select="$thisletter" /></a>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$thisletter" />
</xsl:otherwise>
</xsl:choose>
<xsl:call-template name="process.alphabet">
<xsl:with-param name="letters" select="substring($letters , 2)" />
</xsl:call-template>
</xsl:for-each>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
rgds,
Conor.
Since you are using the msxsl:nodeset element I assume the XML is inside a variable/parameter.
I have placed the XML data inside a param named "pageData".
As a matter of interest what is your stylesheet applied to?? And how is the variable pageData passed to the stylesheet??
<xsl:stylesheet version="1.0" exclude-result-prefixes="m
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-m
<xsl:param name="pageData">
<root><data><alphabet><cha
<alphabet><char>F</char></
</xsl:param>
<xsl:variable name="alphabet" select="'ABCDEFGHIJKLMNOPQ
<xsl:key match="char" name="chars" use="." />
<xsl:template match="/">
<xsl:call-template name="process.alphabet">
<xsl:with-param name="letters" select="$alphabet" />
</xsl:call-template>
</xsl:template>
<xsl:template name="process.alphabet">
<xsl:param name="letters" select="''" />
<xsl:variable name="thisletter" select="substring($letters
<xsl:if test="$letters != ''">
<xsl:for-each select="msxsl:node-set($pa
<xsl:choose>
<xsl:when test="key('chars', $thisletter)">
<a href="{$thisletter}.html">
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$thisletter" />
</xsl:otherwise>
</xsl:choose>
<xsl:call-template name="process.alphabet">
<xsl:with-param name="letters" select="substring($letters
</xsl:call-template>
</xsl:for-each>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
rgds,
Conor.
ASKER
I see what you've done and it works fine, but I just cannot get it to work when I try it to apply it to my "pageData". In fact, it just hangs... I tried to change the
<xsl:for-each select="msxsl:node-set($pa geData)">
to
<xsl:for-each select="msxsl:node-set($pa geData)//a lphabet/." >
but that causes it to die.
What does the <xsl:key match="char" name="chars" use="." /> do?
This is a simplified version of the code in the asp page that sets up the XSL:
xslPage = "pages/xsl/companies.xsl"
xmlPage = "template/xml/main.xml"
pageData = "<root><data><alphabet><ch ar>A</char ></alphabe t><alphabe t><char>C< /char></al phabet><al phabet><ch ar>D</char ></alphabe t>
<alphabet><char>F</char></ alphabet>< alphabet>< char>S</ch ar></alpha bet><alpha bet><char> W</char></ alphabet>< /data></ro ot>"
Set Append = Server.CreateObject("Msxml 2.DOMDocum ent.3.0")
Append.loadXML(xmlMenuID)
xmlDoc.async = false
xslDoc.async = false
xmlDoc.load(server.mapPath (xmlPage))
xslDoc.load(server.mapPath (xslPage))
Set template = Server.CreateObject("MSXML 2.XSLTempl ate")
Set template.stylesheet = xslDoc
Set proc = template.createProcessor
proc.input = xmlDoc
proc.output = Response
proc.addParameter "type", typeID
proc.addParameter "querystring", strQueryString
proc.addParameter "font", Session("font")
proc.addParameter "color", Session("color")
proc.addParameter "pageID", pageID
proc.addParameter "companyID", companyID
proc.addParameter "menuID", Append.documentElement
If pageData <> "" Then
proc.addParameter "pageData", loadData.documentElement
End If
proc.transform()
<xsl:for-each select="msxsl:node-set($pa
to
<xsl:for-each select="msxsl:node-set($pa
but that causes it to die.
What does the <xsl:key match="char" name="chars" use="." /> do?
This is a simplified version of the code in the asp page that sets up the XSL:
xslPage = "pages/xsl/companies.xsl"
xmlPage = "template/xml/main.xml"
pageData = "<root><data><alphabet><ch
<alphabet><char>F</char></
Set Append = Server.CreateObject("Msxml
Append.loadXML(xmlMenuID)
xmlDoc.async = false
xslDoc.async = false
xmlDoc.load(server.mapPath
xslDoc.load(server.mapPath
Set template = Server.CreateObject("MSXML
Set template.stylesheet = xslDoc
Set proc = template.createProcessor
proc.input = xmlDoc
proc.output = Response
proc.addParameter "type", typeID
proc.addParameter "querystring", strQueryString
proc.addParameter "font", Session("font")
proc.addParameter "color", Session("color")
proc.addParameter "pageID", pageID
proc.addParameter "companyID", companyID
proc.addParameter "menuID", Append.documentElement
If pageData <> "" Then
proc.addParameter "pageData", loadData.documentElement
End If
proc.transform()
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Thanks for the help Conor - I'm off on hols imminently for a couple of weeks, so I'm prob not going to get the chance to go through it. Thanks for your advice - I'm not certain the site was created in the cleverest way as it is.
So in the meantime I'll award you the points, as you answered my initial question perfectly.
Cheers,
eq
So in the meantime I'll award you the points, as you answered my initial question perfectly.
Cheers,
eq
try the following. It uses a global variable to store all the letters of the
alphabet and a key to reference the char elements in your XML document.
..............
<xsl:variable name="alphabet" select="'ABCDEFGHIJKLMNOPQ
<xsl:key match="char" name="chars" use="." />
<xsl:template match="/">
<xsl:call-template name="process.alphabet">
<xsl:with-param name="letters" select="$alphabet" />
</xsl:call-template>
</xsl:template>
<xsl:template name="process.alphabet">
<xsl:param name="letters" select="''" />
<xsl:variable name="thisletter" select="substring($letters
<xsl:if test="$letters != ''">
<xsl:choose>
<xsl:when test="key('chars', $thisletter)">
<a href="{$thisletter}.html">
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$thisletter" />
</xsl:otherwise>
</xsl:choose>
<xsl:call-template name="process.alphabet">
<xsl:with-param name="letters" select="substring($letters
</xsl:call-template>
</xsl:if>
</xsl:template>
..............
HTH.
rgds,
Conor.