Passing Parameters to Xslt Stylesheet via .Net

Passing parameters to XSLT Stylesheet via .NET

You need to define the parameter within your XSLT and you also need to pass the XsltArgumentList as an argument to the Transform call:

private static void CreateHierarchy(string manID)
{
string man_ID = manID;

XsltArgumentList argsList = new XsltArgumentList();
argsList.AddParam("Boss_ID", "", man_ID);

XslCompiledTransform transform = new XslCompiledTransform(true);
transform.Load("htransform.xslt");

using (StreamWriter sw = new StreamWriter("output.xml"))
{
transform.Transform("LU AIB.xml", argsList, sw);
}
}

Please note that the xsl:param must be defined below the xsl:stylesheet element:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="yes" />

<xsl:param name="Boss_ID"></xsl:param>

<xsl:template match="OrgDoc">

<!-- template body goes here -->

</xsl:template>

</xsl:stylesheet>

This simple XSLT sample will create just a small output document containing one XML node with its contents set to the value of your parameter. Have a try:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="yes" />
<xsl:param name="Boss_ID"></xsl:param>

<xsl:template match="/">
<out>
<xsl:value-of select="$Boss_ID" />
</out>
</xsl:template>

</xsl:stylesheet>

Pass parameter to XSLT stylesheet

Here is my XSLT:

<xsl:template match="/">     
<xsl:param name="processingId"></xsl:param>
..HTML..
<xsl:value-of select="$processingId"/>

Am I missing something?

Yes, you are missing the fact that the invoker of an XSLT transformation can set the values of global-level parameters -- not the values of template-level parameters.

Therefore, the code must be:

 <xsl:param name="processingId"/>     

<xsl:template match="/">
..HTML..
<xsl:value-of select="$processingId"/>
<!-- Possibly other processing here -->
</xsl:template>

How to pass document type parameter to xslt using saxon?

I think you should use the Processor object to construct an XdmNode, see the documentation which says:

The Processor provides a method NewDocumentBuilder which, as the name
implies, returns a DocumentBuilder. This may be used to construct a
document (specifically, an XdmNode) from a variety of sources. The
input can come from raw lexical XML by specifying a Stream or a Uri,
or it may come from a DOM document built using the Microsoft XML
parser by specifying an XmlNode, or it may be supplied
programmatically by nominating an XmlReader.

Then you can pass in the XdmNode to the SetParameter method http://saxonica.com/documentation/html/dotnetdoc/Saxon/Api/XsltTransformer.html#SetParameter%28Saxon.Api.QName,Saxon.Api.XdmValue%29 as XdmValue is a base class of XdmNode (XmlValue -> XdmItem -> XdmNode).

Here is an example that works for me with Saxon 9.5 HE on .NET:

        Processor proc = new Processor();

DocumentBuilder db = proc.NewDocumentBuilder();

XsltTransformer trans;
using (XmlReader xr = XmlReader.Create("../../XSLTFile1.xslt"))
{
trans = proc.NewXsltCompiler().Compile(xr).Load();
}

XdmNode input, lookup;

using (XmlReader xr = XmlReader.Create("../../XMLFile1.xml"))
{
input = db.Build(xr);
}

using (XmlReader xr = XmlReader.Create("../../XMLFile2.xml"))
{
lookup = db.Build(xr);
}

trans.InitialContextNode = input;

trans.SetParameter(new QName("lookup-doc"), lookup);

using (XmlWriter xw = XmlWriter.Create(Console.Out))
{
trans.Run(new TextWriterDestination(xw));
}

The XSLT is

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
>
<xsl:param name="lookup-doc"/>

<xsl:key name="map" match="map" use="key"/>

<xsl:output method="xml" indent="yes"/>

<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>

<xsl:template match="item">
<xsl:copy>
<xsl:value-of select="key('map', ., $lookup-doc)/value"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>

the XML documents are

<root>
<item>foo</item>
</root>

and

<root>
<map>
<key>foo</key>
<value>bar</value>
</map>
</root>

the resulting output is

<root>
<item>bar</item>
</root>

Pass parameters from C# .cs to .xslt

xsl:

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

<xsl:param name="yourParam" />

public static string Transform(string xml, string xsl, XsltArgumentList argsList)
{
XDocument selectedXml = XDocument.Parse(xml);
XslCompiledTransform xmlTransform = new XslCompiledTransform();

StringBuilder htmlOutput = new StringBuilder();
XmlWriter writer = XmlWriter.Create(htmlOutput);

xmlTransform.Load(new XmlTextReader(new StringReader(xsl)));
xmlTransform.Transform(selectedXml.CreateReader(), argsList, writer);

return htmlOutput.ToString();
}

protected void Page_Load(object sender, EventArgs e)
{

XsltArgumentList xslArg = new XsltArgumentList();

// Add parameters
xslArg.AddParam("chart_url", "","Chart_Url");
xslArg.AddParam("last", "", "Last");
xslArg.AddParam("change", "", "Change");
xslArg.AddParam("perc_change", "", "Perc_Change");

string output=Transform(string.empty,"Home.xslt",xslArg );

Response.Clear();
Response.Write(output);

//or:
//string output=Transform("<xmlroot/>","Home.xslt",xslArg );
}

How can I pass a parameter to my xslt stylesheet with Saxon under Java?

From the message it seems quite obvious that you need to pass an net.sf.saxon.s9api.Qname as the first argument (not just the string "myVar").

And the second argument must be constructed as an net.sf.saxon.s9api.XdmValue.

Just to make sure, is that the good way to send a parameter so I can get it back with

<xsl:param ... /> ?

In your XSLT stylesheets (the primary one and any stylesheet module that is referenced in an xsl:import or an xsl:include directive) you must have a global (child of xsl:stylesheet) xsl:param with the same name as the string used to construct the Qname that you are passing as the first argument to setParameter().

When the setParameter() method is executed and then the transformation is invoked, the corresponding global xsl:param will have the value that was used to construct the XdmValue passed as the second argument to setParameter().

How to pass parameter value to XSL?

Because the value you want as a parameter is in your base XML, you can simply enter a XPath expression for the paramater that specifies a default value.

<xsl:param name="sortKey" select="/ABC/firstname"/> 

Simply using an variable, would also be valid here, if the value was always going to be in the XML

<xsl:variable name="sortKey" select="/ABC/firstname"/> 

And then, to use this parameter/variable, you would simply do something like this

<xsl:template match="/">
<xsl:value-of select="$sortKey" />
</xsl:template>

This would simply output the value GREG

Using a parameter passed into xslt stylesheet

You are using xsl:param inside a xsl:template element, it means that the param is for the template. The parameter you are passing from the .net code is a transformer parameter and related xsl:param must be placed at the top level of the stylesheet, into the xsl:stylesheet element.

Are there limitiations of xsl:param for passing parameters to a stylesheet one should be aware of?

Sounds as if you're using Java and Xalan. Since you're asking about limitations, the answer is going to be specific to the product you are using, so you really need to specify that in the question.

There will be restrictions on what data type you can pass to xsl:param, but it looks as if you are already working around that by encoding the data into a single string, and every processor is likely to accept string values with no trouble.

As to the length of a string, it's very unlikely that any Java processor would imposes a limit shorter than the maximum length of a Java string, which is something like 2^31 characters, and you'll probably run out of memory before you hit that limit.

Passing parameter to stylesheet with saxon

Simply use

<xsl:for-each select="for $x in(collection(concat($MYVAR, '?select=*.xml;recurse=yes')))return saxon:discard-document($x)//testsuites">

Note that MYVAR should be a file URL, not a (platform dependant) directory path.

[edit]
In your XSLT you need

<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="2.0">

<xsl:param name="MYVAR"/>

...

</xsl:stylesheet>

in your Java code use the method http://download.oracle.com/javase/6/docs/api/javax/xml/transform/Transformer.html#setParameter%28java.lang.String,%20java.lang.Object%29 e.g.

transformer.setParameter("MYVAR", "file:///C:/dir/subdir/dir");

How to specify a document as type of parameter in XSLT stylesheet?

Try as="document-node()" for the attribute, the syntax of sequence types used in XSLT 2.0 is defined in the XPath 2.0 specification https://www.w3.org/TR/xpath20/#id-sequencetype-syntax.



Related Topics



Leave a reply



Submit