|
|
|
|
|
|
|
/// <summary>
|
|
/// Applies an xsl transform to a source xml. Accommodates xsl transforms that produce one or more output files.
|
|
/// </summary>
|
|
/// <param name="xsltRoot">The root xsl transform file.</param>
|
|
/// <param name="source">The xml source to transform.</param>
|
|
/// <param name="sourceFileName">The xml source file name.</param>
|
|
/// <param name="transformed">List of transformed output. Key is the file name, Value is the file contents.</param>
|
|
/// <param name="errorMessage">Xslt compile error messages</param>
|
|
/// <returns>True if no errors were encountered.</returns>
|
|
public static bool BasicXslTransform(string xsltRoot, string source, string sourceFileName, out List<KeyValuePair<string, string>> transformed, out string errorMessage)
|
|
{
|
|
transformed = null;
|
|
errorMessage = string.Empty;
|
|
|
|
try
|
|
{
|
|
//=====
|
|
// Create a Saxon Processor instance.
|
|
//=====
|
|
Processor processor = new Processor();
|
|
|
|
var builder = processor.NewDocumentBuilder();
|
|
|
|
// Set the basic settings for the builder
|
|
builder.BaseUri = new Uri("file:///");
|
|
builder.DtdValidation = false;
|
|
|
|
|
|
// Create a process task resolver to ensure that the DTD handling is
|
|
// managed properly.
|
|
ProcessTaskXmlResolver customResolver = new ProcessTaskXmlResolver();
|
|
builder.XmlResolver = customResolver;
|
|
|
|
// Load the source document
|
|
var input = string.IsNullOrWhiteSpace(source) ? builder.Build(new Uri(sourceFileName)) : builder.Build(source.ToStream());
|
|
|
|
// Create a compiler
|
|
XsltCompiler compiler = processor.NewXsltCompiler();
|
|
Xslt30Transformer transformerRoot = compiler.Compile(xsltRoot.ToStream()).Load30();
|
|
|
|
XdmDestination rootResults = new XdmDestination();
|
|
transformerRoot.GlobalContextItem = input;
|
|
|
|
//=====
|
|
// Set the ResultDocumentHandler
|
|
//
|
|
// This is used to process any result documents generated by the transform via the document-result
|
|
// XSLT processing instruction.
|
|
//=====
|
|
Hashtable xmlDocumentResultsHT = new Hashtable();
|
|
transformerRoot.ResultDocumentHandler = new XmlProcessResultDocumentHandlerSaxon(xmlDocumentResultsHT);
|
|
|
|
// Use the default base of "file:///" for generating any output files.
|
|
transformerRoot.BaseOutputURI = "file:///";
|
|
|
|
var tester = transformerRoot.InputXmlResolver;
|
|
|
|
// Apply the root transform to the document
|
|
transformerRoot.ApplyTemplates(input, rootResults);
|
|
|
|
//=====
|
|
// Determine the output file list
|
|
//=====
|
|
transformed = new List<KeyValuePair<string, string>>();
|
|
|
|
// Add the main output file (typical case) where there is
|
|
// a single transformed output file.
|
|
if (!string.IsNullOrWhiteSpace(rootResults.XdmNode?.OuterXml))
|
|
{
|
|
var XmlOutput = rootResults.XdmNode.OuterXml;
|
|
|
|
var kvp = new KeyValuePair<string, string>(sourceFileName, XmlOutput);
|
|
transformed.Add(kvp);
|
|
}
|
|
|
|
// Next add any output files generated from the document-result transform instruction
|
|
foreach (var fileNameResultsKey in xmlDocumentResultsHT.Keys)
|
|
{
|
|
|
|
//Previously:
|
|
//var theXmlOutput = ((DomDestination)xmlDocumentResultsHT[fileNameResultsKey])?.XmlDocument?.OuterXml ?? string.Empty;
|
|
|
|
// CORRECTED:
|
|
var XmlOutput = ((XdmDestination)xmlDocumentResultsHT[fileNameResultsKey])?.XdmNode?.OuterXml;
|
|
|
|
var kvp2 = new KeyValuePair<string, string>(fileNameResultsKey.ToString(), XmlOutput);
|
|
transformed.Add(kvp2);
|
|
}
|
|
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
errorMessage = ex.Message;
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Event Handler for result file creation. This method gets called once
|
|
/// for each document-result operation in the XSLT transform.
|
|
/// </summary>
|
|
/// <param name="href">The filename being generated.</param>
|
|
/// <param name="baseUri">The base URI to use for the filename.</param>
|
|
/// <returns>An XmlDestination object to store the result document content within.</returns>
|
|
public XmlDestination HandleResultDocument(string href, Uri baseUri)
|
|
{
|
|
//DomDestination destination = new DomDestination();
|
|
//ResultDocumentHashtable[href] = destination;
|
|
//return destination;
|
|
|
|
|
|
// CORRECTED: to use XdmDestination
|
|
XdmDestination dest = new XdmDestination();
|
|
|
|
ResultDocumentHashtable[href] = dest;
|
|
return dest;
|
|
}
|