I have this Saxon C# method that takes in an input XML node, and and a string containing an XSLT 2.0 that I generated in MapForce. This function works fine with one XML input node, but I've recently created a mapping with multiple inputs (i.e. 2 xml files and 1 output). So I need to modify the Saxon code to become aware of another input node. However, the XsltTransformer class only seems to have an "InitialContextNode" property and nothing else to specify additional context nodes. Is anyone familiar with how to get the XsltTransformer class to see other XML nodes? Thanks.
public static string transform(string inputXML, string transformText) {
Processor processor = new Processor();
TextReader stringReader = new StringReader(inputXML);
XmlTextReader reader2 = new XmlTextReader(stringReader);
reader2.XmlResolver = null;
XdmNode input = processor.NewDocumentBuilder().Build(reader2);
XsltTransformer transformer = processor.NewXsltCompiler().Compile(new StringReader(transformText)).Load();
transformer.InputXmlResolver = null;
transformer.InitialContextNode = input;
Serializer serializer = new Serializer();
StringBuilder sb = new StringBuilder();
TextWriter txt = new StringWriter(sb);
serializer.SetOutputWriter(txt);
transformer.Run(serializer);
return sb.ToString();
}
So basically what I need is something like this:
public static XElement transform(string transformText, params XElement[] inputXML) {
if (string.IsNullOrEmpty(transformText)) return null;
else {
Processor processor = new Processor();
List<XdmNode> nodes = new List<XdmNode>();
foreach (XElement input in inputXML) {
TextReader stringReader = new StringReader(input.ToString());
XmlTextReader reader2 = new XmlTextReader(stringReader);
reader2.XmlResolver = null;
nodes.Add(processor.NewDocumentBuilder().Build(reader2));
}
XsltTransformer transformer = processor.NewXsltCompiler().Compile(new StringReader(transformText)).Load();
transformer.InputXmlResolver = null;
transformer.InitialContextNode = nodes[0]; // How do I get it to see the other nodes?
Serializer serializer = new Serializer();
StringBuilder sb = new StringBuilder();
TextWriter txt = new StringWriter(sb);
serializer.SetOutputWriter(txt);
transformer.Run(serializer);
return XElement.Parse(sb.ToString());
}
}
XSLT code with 2 inputs for reference: http://pastebin.com/04ZTRe6m
Your stylesheet has a global parameter
<xsl:param name="response2" select="'response.xml'"/>
which I suppose is the file name or URL of the secondary input document. If your input XML is a file of the nameresponse.xml
then you don't have to do anything, if it is a file of a different name then make sure you set the parameter as needed. The stylesheet later on doesdoc($response2)
so it expects a URL.If you want to change the complete approach and want to pass in the secondary input as an
XdmNode
then you would need to change the stylesheet code and you would need to set the parameter to theXdmNode
in your C# code. The main change in the XSLT then would be to simply use$response2
anywhere the stylesheet doesdoc($response2)
.Unrelated to your question I would like to point out that
seems inefficient (as your serialize the XElement to a string to parse the string), the normal way to have an
XmlReader
over anXElement
is simply