How do I pass a parameter from ASP to XSL? - xslt

I'm writing a simple asp page to show a team rota based on some XML. Here's the XML:
<rota>
<shift date="20091201" primary="Chan" secondary="John" notes="notes"></shift>
<shift date="20091202" primary="Mike" secondary="Alex" notes="notes"></shift>
<shift date="20091203" primary="Ross" secondary="Mike" notes="notes"></shift>
<shift date="20091204" primary="Neil" secondary="Ross" notes="notes"></shift>
</rota>
I want my asp page to show today's rota details and maybe the details for the next couple of days. Since later on I'd like to be able to set a day in the future to see who's working around then I want to be able to pass a YYYYMMDD date from the ASP to the XSL that processes the XML.
Here's the XSL I have so far, just highlighting the hardcoded 'current' date for now:
<xsl:template match="rota">
<html>
<head>
<title>Team Rota</title>
<LINK type="text/css" rel="stylesheet" href="http://www.csfb.net/homepage/global/scripts/csfb_intranet.css"/>
</head>
<body>
<table border="1">
<TR><TH>Date</TH><TH>Primary</TH><TH>Secondary</TH><TH>Notes</TH></TR>
<xsl:for-each select="shift">
<tr>
<xsl:choose>
<xsl:when test="#date = '20091203'">
<td bgcolor='FFF0F0'><xsl:value-of select="#date"/></td>
</xsl:when>
<xsl:otherwise>
<td><xsl:value-of select="#date"/></td>
</xsl:otherwise>
</xsl:choose>
<td><xsl:value-of select="#primary"/></td>
<td><xsl:value-of select="#secondary"/></td>
<td><xsl:value-of select="#notes"/></td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
and here's the ASP, not yet passing any parameters:
''// Load the XML
sourcefile = "rota.xml"
set source = Server.CreateObject("Microsoft.XMLDOM")
source.async = false
source.load(sourceFile)
''// Load the XSL
styleFile = Server.MapPath("rota.xsl")
set style = Server.CreateObject("Microsoft.XMLDOM")
style.async = false
style.load(styleFile)
htmltext = source.transformNode(style)
Response.Write htmltext
So how do I a) pass a parameter to the XSL and b) pick up that parameter and use it in the XSL?
Thanks for any guidance.

In you xsl create a xsl:parameter at the top before all your templates.
<xsl:parameter name="showdate"/>
You can now treat this like you would a variable:-
<xsl:when test="#date = $showdate">
In order to pass a parameter in you need to use an XSL processor object which allows you to add the parameter before processing. In turn you get a processor from an instance of an XSL Template object. In turn you need a FreeThreadedDOMDocument to assign to the templates stylesheet parameter. Hence the code is more complex:-
Dim xsl : Set xsl = CreateObject("MSXML2.FreeThreadedDOMDocument.3.0")
xsl.async = false
xsl.load xslFile
Dim xml : Set xml = CreateObject("MSXML2.DOMDocument.3.0")
xml.async = false
xml.load sourceFile
Dim xslTemplate : Set xslTemplate = CreateObject("MSXML2.XSLTemplate.3.0")
xslTemplate.stylesheet = xsl;
Dim processor : Set processor = xslTemplate.createProcessor()
processor.addParameter "showDate", "20091203"
processor.input = source
processor.transform()
Response.Write processor.output
Its tempting to assign the Response object to the processor's output parameter which works quite well and is more efficient. However recent Service packs of MSXML have made such a technique incompatible with ASP's implementation of IStream in the Response object.
So thats how you do it officially, how I do it normally is to inject some arbitary attribute on to the source XML's root node then use a variable:-
xml.documentElement.setAttribute("_showDate", "20091203")
Now you can use a variable instead of a parameter inside your main template:-
<xsl:template match="rota">
<xsl:variable name="showdate" select="#_showDate" />
<html> ...
<xsl:when test="#date = $showdate">
In this approach you can use the transform code you are already using which is much simpler.

You should declare your parameter like this:
<xsl:stylesheet ... >
<xsl:parameter name="your_parameter"/>
<xsl:template match="rota">
$your_parameter = <xsl:value-of select="$your_parameter" />
...
And pass it like this
'// Load the XSL
styleFile = Server.MapPath("rota.xsl")
set style = Server.CreateObject("MSXML2.FreeThreadedDOMDocument.3.0")
style.async = false
style.load(styleFile)
Set template = Server.CreateObject("MSXML2.XSLTemplate.3.0")
template.stylesheet = style
Set processor = myTemplate.createProcessor()
processor.addParameter "your_parameter", "value"
processor.input = source
processor.output = Response
processor.transform()

Related

Unable to get the value of 'xml:lang' attribute

<xoe:documents xmlns:xoe="http://xxxxxx" count="1">
<xocs:doc xmlns:xocs="xxxxxx" xmlns:xsi="yyyyyyy" xsi:schemaLocation="zzzzzz">
<xocs:meta>...</xocs:meta>
<xocs:serial-item>
<!-- this line -->
<article xmlns:sa="www.google.hgy" xmlns="http://www.xyzq1.org/xml/ja/dtd" version="5.4" xml:lang="pl" docsubtype="rev">
<article-info>
</article-info>
</article>
</xocs:serial-item>
</xocs:doc>
</xoe:documents>
I am unable to get the value of 'xml:lang' attribute. Even thought I tried with the below xpath
<xsl:variable name="rootPath" select="/xoe:documents/xocs:doc/xocs:serial-item"/>
<xsl:variable name="lang" select="$rootPath/ja:article[#xml:lang]"/>
or
<xsl:variable name="lang" select="$rootPath/ja:article/#xml:lang"/>
here ja is already defined in my xslt code
xmlns:ja="http://www.xyzq1.org/xml/ja/dtd"
Can some one please help?
First, you need to declare these:
xmlns:xoe="http://xxxxxx"
xmlns:xocs="xxxxxx"
xmlns:ya="www.yahoo.mkt"
Then you can get the value of the xml:lang attribute using:
<xsl:value-of select="/xoe:documents/xocs:doc/xocs:serial-item/ya:article/#xml:lang"/>
Note that the URIs in your stylesheet namespace declarations must be the same URIs that appear in your source XML. The prefixes can be anything you like.

Ampersand URL parameters in document function

If I want to load a document into a variable, I can use
<xsl:variable name="var1" select="document('http://www.mySite.com/file1.xml')" />
=> works, I can use -
<xsl:value-of select="$var1//myNodeName"/>
but now I need to use a URL with parameter.
and the following tests do not work -
<xsl:variable name="var2" select="document('http://www.mySite.com/getfile.cgi?param1=val1&param2=val2')" />
=> does not work - EntityRef: expecting ';'
<xsl:variable name="var2" select="document('http://www.mySite.com/getfile.cgi?param1=val1&param2=val2')" />
=> does not work - warn for wrong URL -
http://www.mySite.com/getfile.cgi?param1=val1&param2=val2:1:
why does it add :1: ???
My Question:
How do I replace the & entity to make the document() function work?
Update:
according to -
http://our.umbraco.org/forum/developers/xslt/5421-Ampersand-in-XSLT
the solution is to store the URL as a variable, then output it disablig output escaping.
e.g.
<xsl:variable name="test" select="http://www.mysite.com/mypage.aspx?param1=1&param2=2" />
<xsl:value-of select="$test" disable-output-escaping="yes" />
but, how can I apply this solution with document() parameter?
Update 2:
I parse it using PHP -
<?php
Header('Content-type: text/xml');
// http://php.net/manual/en/xsltprocessor.transformtoxml.php
$xml = new DOMDocument;
$xml->load('http://www.mySite.com/devices.xml');
$xsl = new DOMDocument;
$xsl->load('mergedocs.xsl');
// Configure the transformer
$proc = new XSLTProcessor;
$proc->importStyleSheet($xsl); // attach the xsl rules
echo $proc->transformToXML($xml);
?>
The error I get [note the amp within the URL]:
XML Parsing Error: junk after document element
Location: http://mySite/myPhpFile.php
Line Number 2, Column 1:<b>Warning</b>: XSLTProcessor::transformToXml() [<a href='xsltprocessor.transformtoxml'>xsltprocessor.transformtoxml</a>]:
http://siteIp/cgi-bin/getfile.cgi?p1=v1&p2=v2:1: parser error : Document is empty
in <b>/home/.../myPhpFile.php</b> on line <b>16</b><br />
Encoding the & as & is the correct approach, the URL retrieved by the processor will be the correct one with val1&param2. I suspect the :1: isn't part of the URL but rather part of the warning message i.e. problem at ::

Xslt expression [.=

I have here a small XSLT code, but I don't understand one of the expressions and also one of my added values doesn't work.
Here is what i have:
<xsl:choose>
<xsl:when test="contentclass[. = 'STS_ListItem_DocumentLibrary'] and {imageurl/#imageurldescription} = 'Web Page'">
<div class="srch-Icon" id="{concat($currentId,'_Icon')}">
<img align="absmiddle" src="/_layouts/images/itdl.png" border="0" alt="Document Library" />
</div>
</xsl:when>
<xsl:otherwise>
<div class="srch-Icon" id="{concat($currentId,'_Icon')}">
<img align="absmiddle" src="{imageurl}" border="0" alt="{imageurl/#imageurldescription}" />
</div>
</xsl:otherwise>
Basically as you see, what does this expression means => "[.="?
And secondly this doenst work, anyone know why?
{imageurl/#imageurldescription} = 'Web Page'
Why the problem can exist?
The value exists 100% as in default call it works (in otherwise i do get value there)
{ } around an expression in an attribute on a normal element will make the XSLT engine evaluate it, instead of treat it as text. In most attributes on control-elements (<xsl:...), the curly braces are not needed, and there will be a syntax error if you include them.
The contentclass[. = 'STS_ListItem_DocumentLibrary'] part means: Match all child contentclass elements whenever their content is "STS_ListItem_DocumentLibrary". It is equivalent to: contentclass = 'STS_ListItem_DocumentLibrary'
Read more:
XSLT 1.0: Attribute Value Templates

Replace text in XSL with conditional statements

I am working with XML files that are generated by a digital video camera. The camera allows the user to save all of the camera's settngs to an SD card so that the settings can be recalled or loaded into another camera. The XSL stylesheet I am writing will allow users to view the camera's settings, as saved to the SD card in a web browser.
While most of the values in the XML file -- as formatted by my stylesheet -- make sense to humans, some do not. What I would like to do is have the stylesheet display text that is based on the value in the XML file but more easily understood by humans.
My sample XML file may be viewed here: http://josephthomas.info/Alexa/Setup_120511_140322.xml
A few lines down the page you will see:
Color GAMMA-SxS Rec_Log
While "Rec_Log" is a value that the cameras understand, it is not a value that the camera's users will understand. What I would like for the stylesheet to do is to display "LogC" instead.
In the XML file this value is defined thusly:
<DteLut lowerLimit="0" upperLimit="2">Rec_Log</DteLut>
The XSL formatting the sample page for this value is:
<tr>
<td class="title_column">Color GAMMA-SxS</td><td><xsl:value-of select="Settings/Groups/Recording/DteLut"/>
</td>
</tr>
So what I hope to do is have "LogC" displayed on the page rather than Rec_Log.
It seems to me that the "when" conditional statement is the correct approach, but I am not familiar enough with the syntax to cause this to happen. There are other values in the XML file that want replacing but the above is a good example of my mission.
What you could do is make use of make use of template matching, to match the exceptions to what you want to change. Firstly, add the following template to your XSL
<xsl:template match="DteLut[. = 'Rec_Log']">
<xsl:text>LogC</xsl:text>
</xsl:template>
Then, instead of the following line
<xsl:value-of select="Settings/Groups/Recording/DteLut"/>
Do the following line
<xsl:apply-templates select="Settings/Groups/Recording/DteLut"/>
When the value of*DteLut* is "Rec_Log", then the custom template will be matched to output "LogC" instead. When there is not a match, the default behaviour will kick in which will be to just output the text value as-is.
I would use a data-driven approach. Have a mapping file that gives all the translations:
<translations>
<translate from="Rec_log" to="LogC"/>
<translate .../>
</translations>
then define a key:
<xsl:key name="trans" match="translate" use="#from"/>
and then change
<xsl:value-of select="Settings/Groups/Recording/DteLut"/>
to
<xsl:value-of select="key('trans', Settings/Groups/Recording/DteLut,
doc('translations.xml'))/#to"/>
if using XSLT 2.0, or
<xsl:variable name="val" select="Settings/Groups/Recording/DteLut"/>
<xsl:for-each select="document('translations.xml')">
<xsl:value-of select="key('trans', $val)/#to"/>
</xsl:for-each>
if you're stuck with 1.0.

How do I access the querystring in an Umbraco template?

I'm trying to get hold of the querystring directly from the template in Umbraco, but can't seem to figure it out..
For example:
/mypage.aspx?p=bek
I can do it with <%=HttpContext.Current.Request["p"]%>, but I want it in a field...
Something like this:
Any ideas?
Ok, so I fixed it.
Found this:
http://forum.umbraco.org/yaf_postst6663_Get-querystring-in-template.aspx
If anyone else is interested, you do the following..
Create a xslt file with the name "QueryStringExtractor" and paste the below code where it belongs.
<xsl:param name="currentPage"/>
<xsl:variable name="yourvalue" select="//macro/myparam" />
<xsl:template match="/">
<!-- start writing XSLT -->
<xsl:value-of select="$yourvalue" />
</xsl:template>
Save and update the Umbraco page and you'll see a macro under "Macros" with the same namne.
In the macro you add the parameter "myparam" (I put it as text). Save!
Then in your template just past the following code and you're good to go!
<ul>
<umbraco:Macro Alias="QueryStringExtractor" myparam="[#p]" runat="server"></umbraco:Macro>
</ul>
So now when you enter the querystring "?p=something" you'll get "something" written on the page.
Notice that you can pass any "p" to the macro.
Hope this helps someone else!