supplying runtime parameter

S

sp

the xml file i used


<catalog>
<cd>
<title year="1990">Empire Burlesque</title>
<artist>Bob Dylan</artist>
<price>10.90</price>
</cd>
<cd>
<title year="1995">Hide your heart</title>
<artist>Bonnie Tyler</artist>
<price>9.90</price>
</cd>
<cd>
<title year="1995">Greatest Hits</title>
<artist>Dolly Parton</artist>
<price>9.90</price>
</cd>
<cd>
<title year="1995">Still got the blues</title>
<artist>Gary Moore</artist>
<price>10.20</price>
</cd>
<cd>
<title year="1998">Eros</title>
<artist>Eros Ramazzotti</artist>
<price>9.90</price>
</cd>
<cd>
<title year="1998">One night only</title>
<artist>Bee Gees</artist>
<price>10.90</price>
</cd>
</catalog>


the output expected


<cd>
<title year="1990">Empire Burlesque</title>
<artist>Bob Dylan</artist>
<price>10.90</price>
</cd>


the xsl used


<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:eek:utput method="xml" />
<xsl:template match="/">
<xsl:for-each select="/catalog/cd[title[@year='1990']]">
<catalog>
<xsl:copy-of select="." />
</catalog>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>



in the above xsl i am filtering the xml by hardcoding the value of year
is there any way to pass the filtering parameter as a runtime argument
( i am working in C++ )

by using the transformNode function i am abel to apply the filtering in
XSL but how can i pass the filter parameter runtime

could anyone help in this issue

thanks
praveen
 
M

Martin Honnen

sp wrote:


<xsl:for-each select="/catalog/cd[title[@year='1990']]">
in the above xsl i am filtering the xml by hardcoding the value of year
is there any way to pass the filtering parameter as a runtime argument

Yes, your stylesheet can declare a global parameter
<xsl:param name="inputYear" />
then you need to check the API documentation of your XSLT processor on
how to set that parameter before running a transformation e.g. there
will a method alike
xsltProcessor.addParameter('inputYear', '2000')
( i am working in C++ )

by using the transformNode function i am abel to apply the filtering in
XSL but how can i pass the filter parameter runtime

Which processor are you using, some version of Microsoft MSXML?
API docs are here:
<http://msdn.microsoft.com/library/d...html/9ddcd728-2646-494a-8fa4-3b68e8c032b7.asp>


Note however that your example does not need a stylesheet at all, a
simple XPath expression evaluation (e.g. selectNodes, selectSingleNode
with MSXML) would give you the result as you do not seem to want to
create any nodes, you simple select one cd element and that can be done
with pure XPath without using XSLT e.g.:
xmlDocument.setProperty('SelectionLanguage', 'XPath');
var someInputYear = '2000';
var cdElement = xmlDocument.selectSingleNode(
'/catalog/cd[title[@year = "' + someInputYear + '"]]');
 
G

gimme_this_gimme_that

This you might find this java utility class helpful ....
I use it to dynamically add a xsl:variable to an xsl transform.


package acme.com;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Iterator;
import java.util.Map;

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.FactoryConfigurationError;
import javax.xml.parsers.ParserConfigurationException;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.Text;
import org.xml.sax.SAXException;

public class XSLUtils {
public static InputStream addParameters(InputStream xsl, Map
parameters) {
Document document = null;
try {
document =
DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(xsl);

Node root = document.getDocumentElement();

Iterator iterator = parameters.keySet().iterator();
while(iterator != null && iterator.hasNext()) {
String name = (String)iterator.next();
String value = (String)parameters.get(name);

Node element = document.createElement("xsl:variable");
NamedNodeMap attributes = element.getAttributes();
Attr nameAttr = document.createAttribute("name");
nameAttr.setNodeValue(name);
attributes.setNamedItem(nameAttr);

Text textNode = document.createTextNode(value);
element.appendChild(textNode);

root.insertBefore(element, root.getFirstChild());
}

// now convert document to an InputStream
return new
ByteArrayInputStream(XMLTransformer.transform(document,
false).getBytes());
} catch(SAXException e) {
LOG.error(e);
} catch(IOException e) {
LOG.error(e);
} catch(ParserConfigurationException e) {
LOG.error(e);
} catch(FactoryConfigurationError e) {
LOG.error(e);
} catch(XMLTransformException e) {
LOG.error(e);
} finally {
StreamUtils.close(xsl);
}

return null;
}
}

Then to use it ...

StringBuffer sb = new StringBuffer();
sb.append("<?xml version=\"1.0\"
encoding=\"UTF-8\"?>");
sb.append(xml.generateXml()); // result of
xml.generateXml() is a string of XML
xmlStream = new
ByteArrayInputStream(sb.toString().getBytes("UTF-8"));

InputStream xslStream =
getServletContext().getResourceAsStream("/WEB-INF/xsl/joborder-email-template.xsl");
xslStream = XSLUtils.addParameters(xslStream, params); //
xsl:variables added here.

// apply transform to XML to generate HTML
String html = DoWhatYouHaveToTo.transform(xmlStream, xslStream);



// add xsl variable assignments
xslStream = XSLUtils.addParameters(xslStream, params);

// apply transform to XML to generate HTML
String html = XSLTransformer.transform(xmlStream,
xslStream);
 
P

Philippe Poulard

hi,

you could use RefleX for this purpose :
http://reflex.gforge.inria.fr/

a very simple script can be done like this :

<?xml version="1.0" encoding="iso-8859-1"?>
<xcl:active-sheet xmlns:xcl="http://www.inria.fr/xml/active-tags/xcl">
<xcl:transform output="/path/to/file.html"
source="/path/to/file.xml" stylesheet="/path/to/stylesheet.xsl">
<xcl:param name="inputYear" value="1990"/>
</xcl:transform>
</xcl:active-sheet>

inside your stylesheet, just declare the parameter :
<xsl:param name="inputYear"/>
and change the hard-coded value where expected :
<xsl:for-each select="/catalog/cd[title[@year=$inputYear]]">

notice that for this example, you don't need a stylesheet, you can get
directly the output like this :
<?xml version="1.0" encoding="iso-8859-1"?>
<xcl:active-sheet xmlns:xcl="http://www.inria.fr/xml/active-tags/xcl">
<xcl:parse name="myCatalog" source="/path/to/file.xml"/>
<xcl:transform output="/path/to/file.html" source="{
$myCatalog/catalog/cd[title/@year = '1990'] }"/>
</xcl:active-sheet>

the difference is that there is no stylesheet specified, so it is a
simple copy of the node selected

notice that such scripts could be launched in batch mode as well as in
Web application, and you can of course pass parameters from the
environment (batch) or from the URL query string (HTTP)

have a look at the RefleX web site
the xml file i used


<catalog>
<cd>
<title year="1990">Empire Burlesque</title>
<artist>Bob Dylan</artist>
<price>10.90</price>
</cd>
<cd>
<title year="1995">Hide your heart</title>
<artist>Bonnie Tyler</artist>
<price>9.90</price>
</cd>
<cd>
<title year="1995">Greatest Hits</title>
<artist>Dolly Parton</artist>
<price>9.90</price>
</cd>
<cd>
<title year="1995">Still got the blues</title>
<artist>Gary Moore</artist>
<price>10.20</price>
</cd>
<cd>
<title year="1998">Eros</title>
<artist>Eros Ramazzotti</artist>
<price>9.90</price>
</cd>
<cd>
<title year="1998">One night only</title>
<artist>Bee Gees</artist>
<price>10.90</price>
</cd>
</catalog>


the output expected


<cd>
<title year="1990">Empire Burlesque</title>
<artist>Bob Dylan</artist>
<price>10.90</price>
</cd>


the xsl used


<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:eek:utput method="xml" />
<xsl:template match="/">
<xsl:for-each select="/catalog/cd[title[@year='1990']]">
<catalog>
<xsl:copy-of select="." />
</catalog>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>



in the above xsl i am filtering the xml by hardcoding the value of year
is there any way to pass the filtering parameter as a runtime argument
( i am working in C++ )

by using the transformNode function i am abel to apply the filtering in
XSL but how can i pass the filter parameter runtime

could anyone help in this issue

thanks
praveen


--
Cordialement,

///
(. .)
--------ooO--(_)--Ooo--------
| Philippe Poulard |
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,982
Messages
2,570,186
Members
46,740
Latest member
JudsonFrie

Latest Threads

Top