How to create an XSLT stylesheet - c#

I have access to Schematron xsl files and a Schematron sch file. How can I transform this into an XSLT stylesheet using C# ?
xsl + sch --> [??? XSLT Processor ??? ] --> xslt stylesheet

To answer my own question...
This works, unfortunately the Schematron files only support a very simple syntax using XslCompiledTransform. On to SAXON to see it that works :(
string xmlFile = #"sch\patient.sch";
string xslFile = #"xsl\conformance1-5.xsl";
XslCompiledTransform xsltransform = new XslCompiledTransform();
xsltransform.Load(xslFile);
XmlDocument doc = new XmlDocument();
doc.Load(xmlFile);
XPathNavigator nav = doc.CreateNavigator();
System.IO.MemoryStream st = new System.IO.MemoryStream();
xsltransform.Transform(nav, null, st);
st.Position = 0;
System.IO.StreamReader rd = new System.IO.StreamReader(st);
string xslt = rd.ReadToEnd();
System.Diagnostics.Debug.WriteLine(xslt);
XmlReader reader = XmlReader.Create(new System.IO.StringReader(xslt));
xsltransform.Load(reader);
var patient = PatientFactory.GeneratePatientBySOAPClasses();
patient.identifier[0].period.end.value = DateTime.Now.ToString("yyyy-MM-dd");
patient.identifier[0].period.start.value = DateTime.Now.AddYears(15).ToString("yyyy-MM-dd");
patient.identifier[0].period.start = null;
string xml = Serialization.SerializeXML(patient, "http://hl7.org/fhir");
xml = xml.Replace("xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns=\"http://hl7.org/fhir\"", "");
doc.LoadXml(xml);
nav = doc.CreateNavigator();
st = new System.IO.MemoryStream();
xsltransform.Transform(nav, null, st);
st.Position = 0;
rd = new System.IO.StreamReader(st);
string scematronresult = rd.ReadToEnd();

Related

convert json to xml and save result to a file

I'm converting a JSON string to an XML node like this:
public ActionResult Test(string json)
{
System.Xml.XmlNode myXmlNode = JsonConvert.DeserializeXmlNode("{\"root\":" + json + "}", "root");
How can I save myXmlNode to an external file, say test.xml?
Thanks
This should do it:
var xdoc = XDocument.Load(new StringReader(myXmlNode.ToString()), LoadOptions.None);
xdoc.Save(#"c:\temp\test.xml", SaveOptions.None);
UPDATE:
using (StreamWriter writer = new StreamWriter(Server.MapPath("~/test.xml")))
{
writer.WriteLine(myXmlNode.OuterXml);
}
XmlDocument doc = new XmlDocument();
doc.LoadXml(myXmlNode);
XmlTextWriter writer = new XmlTextWriter("yourfilename.xml",null);
writer.Formatting = Formatting.Indented;
doc.Save(writer);

XSLT transformation for Word

I'm writing a web service in .NET C# that takes in an object, converts it to xml, applies an XSLT template, runs the transformation, and returns an MS work file.
Here is the code for the function:
public static HttpResponseMessage Transform(object data)
{
var response = new HttpResponseMessage(HttpStatusCode.OK);
StringWriter stringWriter = new StringWriter();
XmlWriter xmlWriter = XmlWriter.Create(stringWriter);
var applicationDirectory = AppDomain.CurrentDomain.BaseDirectory;
var xsltPath = applicationDirectory + #"\Reporting\Files\Template.xslt";
var templatePath = applicationDirectory + #"\Reporting\Files\Template.docx";
var xmlObject = new System.Xml.Serialization.XmlSerializer(data.GetType());
MemoryStream stream;
using (stream = new MemoryStream())
{
var sw = new StreamWriter(stream);
xmlObject.Serialize(stream, data);
stream.Position = 0;
XslCompiledTransform transform = new XslCompiledTransform();
transform.Load(xsltPath);
using (XmlReader xmlReader = XmlReader.Create(stream))
{
transform.Transform(xmlReader, xmlWriter);
XmlDocument newWordContent = new XmlDocument();
newWordContent.LoadXml(stringWriter.ToString());
var outputPath = applicationDirectory + #"\Reporting\Temp\temp.docx";
System.IO.File.Copy(templatePath, outputPath, true);
using (WordprocessingDocument output = WordprocessingDocument.Open(outputPath, true))
{
Body updatedBodyContent = new Body(newWordContent.DocumentElement.InnerXml);
output.MainDocumentPart.Document.Body = updatedBodyContent;
output.MainDocumentPart.Document.Save();
}
response.Content = new StreamContent(new FileStream(outputPath, FileMode.Open, FileAccess.Read));
response.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment");
response.Content.Headers.ContentDisposition.FileName = outputPath;
}
}
return response;
}
When I make a request, it gives me a word file without the data.
I put a breakpoint at using (XmlReader xmlReader = XmlReader.Create(stream)).
After running that line, xmlReader has a value of {None}.
I'm also trying to avoid creating an XML file for efficiency(Hence MemoryStream).
Any idea why this isn't working? And is there a better way of accomplishing this?
Thanks,
Gerson
What happens if you change this:
Body updatedBodyContent = new Body(newWordContent.DocumentElement.InnerXml);
to this:
Body updatedBodyContent = new Body(newWordContent.InnerXml);
or this:
Body updatedBodyContent = new Body(newWordContent.DocumentElement.OuterXml);
The way you have it there would cause the outer element of the transformed XML to be omitted, and I doubt that's what you want (though can't say for sure because you've shown us neither the input XML or the XSLT.

Add An XML Declaration To String Of XML

I have some xml data that looks like..
<Root>
<Data>Nack</Data>
<Data>Nelly</Data>
</Root>
I want to add "<?xml version=\"1.0\"?>" to this string. Then preserve the xml as a string.
I attempted a few things..
This breaks and loses the original xml string
myOriginalXml="<?xml version=\"1.0\"?>" + myOriginalXml;
This doesnt do anything, just keeps the original xml data with no declaration attached.
XmlDocument doc = new XmlDocument();
doc.LoadXml(myOriginalXml);
XmlDeclaration declaration = doc.CreateXmlDeclaration("1.0", "UTF-8","no");
StringWriter sw = new StringWriter();
XmlTextWriter tx = new XmlTextWriter(sw);
doc.WriteTo(tx);
string xmlString = sw.ToString();
This is also not seeming to have any effect..
XmlDocument doc = new XmlDocument();
doc.LoadXml(myOriginalXml);
XmlDeclaration declaration = doc.CreateXmlDeclaration("1.0", "UTF-8", "no");
MemoryStream xmlStream = new MemoryStream();
doc.Save(xmlStream);
xmlStream.Flush();
xmlStream.Position = 0;
doc.Load(xmlStream);
StringWriter sw = new StringWriter();
XmlTextWriter tx = new XmlTextWriter(sw);
doc.WriteTo(tx);
string xmlString = sw.ToString();
Use an xmlwritersettings to achieve greater control over saving. The XmlWriter.Create accepts that setting (instead of the default contructor)
var myOriginalXml = #"<Root>
<Data>Nack</Data>
<Data>Nelly</Data>
</Root>";
var doc = new XmlDocument();
doc.LoadXml(myOriginalXml);
var ms = new MemoryStream();
var tx = XmlWriter.Create(ms,
new XmlWriterSettings {
OmitXmlDeclaration = false,
ConformanceLevel= ConformanceLevel.Document,
Encoding = UTF8Encoding.UTF8 });
doc.Save(tx);
var xmlString = UTF8Encoding.UTF8.GetString(ms.ToArray());

How to create rtf using xml xslt and c#

I have created an xml document and an xslt document and now i want to create a word doc/rtf using these through using c#.
I have found the following code on the internet however I can't find a way to use it because I'm not using datasets. I just want the program to read the xml and the xslt combine the two and create a word document
Any help would be really appreciated
DataSet ds;
XmlDataDocument xmlDoc;
XslCompiledTransform xslTran;
XmlElement root;
XPathNavigator nav;
XmlTextWriter writer;
try
{
//Create the DataSet from the XML file
ds = new DataSet();
ds.ReadXml("Employee.xml");
//Create the XML from the DataSet
xmlDoc = new XmlDataDocument(ds);
//Load the XSLT for Transformation
xslTran = new XslCompiledTransform();
xslTran.Load("Employee.xslt");
//Determine the Root object in the XML
root = xmlDoc.DocumentElement;
//Create the XPath Navigator to navigate throuth the XML
nav = root.CreateNavigator();
//First delete the RTF, if already exist
if (File.Exists("Employee.rtf"))
{
File.Delete("Employee.rtf");
}
//Create the RTF by Transforming the XML and XSLT
writer = new XmlTextWriter("Employee.rtf", System.Text.Encoding.Default);
xslTran.Transform(nav, writer);
//Close the Writer after Transformation
writer.Close();
//Release all objects
writer = null;
nav = null;
root = null;
xmlDoc = null;
ds = null;
MessageBox.Show("Document created successfully.....");
}
catch (Exception ex)
{
writer = null;
nav = null;
root = null;
xmlDoc = null;
ds = null;
MessageBox.Show(ex.StackTrace);
}
}
Read http://msdn.microsoft.com/en-us/library/0610k0w4.aspx, it tells you how to use XslCompiledTransform. If you want to transform from a file and output a file then all you need is
XslCompiledTransform proc = new XslCompiledTransform();
proc.Load("stylesheet.xslt");
proc.Transform("input.xml", "output.rtf");

How to create an XML document from a .NET object?

I have the following variable that accepts a file name:
var xtr = new XmlTextReader(xmlFileName) { WhitespaceHandling = WhitespaceHandling.None };
var xd = new XmlDocument();
xd.Load(xtr);
I would like to change it so that I can pass in an object. I don't want to have to serialize the object to file first.
Is this possible?
Update:
My original intentions were to take an xml document, merge some xslt (stored in a file), then output and return html... like this:
public string TransformXml(string xmlFileName, string xslFileName)
{
var xtr = new XmlTextReader(xmlFileName) { WhitespaceHandling = WhitespaceHandling.None };
var xd = new XmlDocument();
xd.Load(xtr);
var xslt = new System.Xml.Xsl.XslCompiledTransform();
xslt.Load(xslFileName);
var stm = new MemoryStream();
xslt.Transform(xd, null, stm);
stm.Position = 1;
var sr = new StreamReader(stm);
xtr.Close();
return sr.ReadToEnd();
}
In the above code I am reading in the xml from a file. Now what I would like to do is just work with the object, before it was serialized to the file.
So let me illustrate my problem using code
public string TransformXMLFromObject(myObjType myobj , string xsltFileName)
{
// Notice the xslt stays the same.
// Its in these next few lines that I can't figure out how to load the xml document (xd) from an object, and not from a file....
var xtr = new XmlTextReader(xmlFileName) { WhitespaceHandling = WhitespaceHandling.None };
var xd = new XmlDocument();
xd.Load(xtr);
}
You want to turn an arbitrary .NET object into a serialized XML string? Nothing simpler than that!! :-)
public string SerializeToXml(object input)
{
XmlSerializer ser = new XmlSerializer(input.GetType(), "http://schemas.yournamespace.com");
string result = string.Empty;
using(MemoryStream memStm = new MemoryStream())
{
ser.Serialize(memStm, input);
memStm.Position = 0;
result = new StreamReader(memStm).ReadToEnd();
}
return result;
}
That should to it :-) Of course you might want to make the default XML namespace configurable as a parameter, too.
Or do you want to be able to create an XmlDocument on top of an existing object?
public XmlDocument SerializeToXmlDocument(object input)
{
XmlSerializer ser = new XmlSerializer(input.GetType(), "http://schemas.yournamespace.com");
XmlDocument xd = null;
using(MemoryStream memStm = new MemoryStream())
{
ser.Serialize(memStm, input);
memStm.Position = 0;
XmlReaderSettings settings = new XmlReaderSettings();
settings.IgnoreWhitespace = true;
using(var xtr = XmlReader.Create(memStm, settings))
{
xd = new XmlDocument();
xd.Load(xtr);
}
}
return xd;
}
You can serialize directly into the XmlDocument:
XmlDocument doc = new XmlDocument();
XPathNavigator nav = doc.CreateNavigator();
using (XmlWriter w = nav.AppendChild())
{
XmlSerializer ser = new XmlSerializer(typeof(MyType));
ser.Serialize(w, myObject);
}
Expanding on #JohnSaunders solution I wrote the following generic function:
public XmlDocument SerializeToXml<T>(T source) {
var document = new XmlDocument();
var navigator = document.CreateNavigator();
using (var writer = navigator.AppendChild()) {
var serializer = new XmlSerializer(typeof(T));
serializer.Serialize(writer, source);
}
return document;
}

Categories