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
Cookie Authentication Expiring Too Soon in ASP.NET Core
How Does Stringbuilder Work Internally in C#
Is There an Entity Framework 7 Database-First Poco Generator
Why Does My .Net Application Crash When Run from a Network Drive
Deserialize JSON String to Dictionary<String,Object>
How to Log All Thrown Exceptions
Why Visual Studio Doesn't Create a Public Class by Default
Streamwriter.Write Doesn't Write to File; No Exception Thrown
Check If Datetime Instance Falls in Between Other Two Datetime Objects
How to Generate and Auto Increment Id with Entity Framework
How to Calculate Divide and Modulo for Integers in C#
Linq - What Is the Quickest Way to Find Out Deferred Execution or Not
Httpwebrequest Times Out on Second Call