Project

Profile

Help

Bug #5480 » SaxonSampleCode.cs

John Crane, 2022-05-11 17:17

 



/// <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;
}
(2-2/2)