I've generated a HTML file and the top html declaration looks like this:
<html xml:lang="de-CH" lang="de-CH" xmlns="http://www.w3.org/1999/xhtml">
And then I try to convert it into a different format with this .Net 4 code:
XmlReaderSettings settings = new XmlReaderSettings();
settings.DtdProcessing = DtdProcessing.Ignore;
XslCompiledTransform proc = new XslCompiledTransform();
proc.Load("Html_to_Sql.xslt");
fsHtmlXml = new FileStream(file.Name, FileMode.Create);
html = XmlReader.Create(file.FullName, settings);
proc.Transform(html, null, fsHtmlXml);
Unfortunately nothing happens as long as I have the xml, lang and xmlns attributes in the HTML.
Why is that?
Your XSLT will need to refer to elements in the http://www.w3.org/1999/xhtml namespace. You haven't posted your XSLT code yet, the the problem most likely lies in that file.
Will this work via XML and XPath
using System;
using System.IO;
using System.Xml;
using System.Xml.Xsl;
using System.Xml.XPath;
public class TransformXML
{
//This will transform xml document using xslt and produce result xml document
//and display it
public static void Main(string[] args)
{
try
{
XPathDocument myXPathDocument = new XPathDocument(sourceDoc);
XslTransform myXslTransform = new XslTransform();
XmlTextWriter writer = new XmlTextWriter(resultDoc, null);
myXslTransform.Load(xsltDoc);
myXslTransform.Transform(myXPathDocument, null, writer);
writer.Close();
StreamReader stream = new StreamReader (resultDoc);
Console.Write("**This is result document**\n\n");
Console.Write(stream.ReadToEnd());
}
catch (Exception e)
{
Console.WriteLine ("Exception: {0}", e.ToString());
}
}
}
The xmlns attribute specifies the namespace of the XML document. This works in much the same way as namespaces within C#, where two classes with the same name but different namespaces are considered to be completely different classes. Changing the XML namespaces means that your XSLT templates / XPath will not match.
Related
I've been using this function to read XML from a string and apply an XSLT style sheets, it has been working very well for small portions of XML:
private static string TransformXML(String XML, String XSLT)
{
string output = String.Empty;
using (StringReader srt = new StringReader(XSLT))
{
using (StringReader sri = new StringReader(XML))
{
using (XmlReader xrt = XmlReader.Create(srt))
using (XmlReader xri = XmlReader.Create(sri))
{
XslCompiledTransform xslt = new XslCompiledTransform();
xslt.Load(xrt);
using (StringWriter sw = new StringWriter())
using (XmlWriter xwo = XmlWriter.Create(sw, xslt.OutputSettings)) // use OutputSettings of xsl, so it can be output as HTML
{
xslt.Transform(xri, xwo);
output = sw.ToString();
}
}
}
}
return output;
}
However, with large portions of XML, I'm getting errors, even though I know it is correctly formatted.
Here is an example error: Unexpected end of file while parsing Name has occurred. Line 1, position 30001.
I'm guessing there is a limit on the buffering, but I can't quite work it out - the code is within an SSIS package and different script tasks produce and translate the XML.
I appreciate any help!
So I retrieve an XML and XSLT as strings from the DB then used my custom HTML helper called RenderXml to render. The problem is that it is not rendering properly. In my HTML helper is where I do the transformation
public static HtmlString RenderXml(this HtmlHelper helper, string theXml, string theXslt)
{
XDocument xmlTree = XDocument.Parse(xmlPath);
XDocument newTree = new XDocument();
using (XmlWriter writer = newTree.CreateWriter())
{
// Load the style sheet.
XslCompiledTransform xslt = new XslCompiledTransform();
xslt.Load(XmlReader.Create(new StringReader(xsltPath)));
// Execute the transform and output the results to a writer.
xslt.Transform(xmlTree.CreateReader(), writer);
return new HtmlString(newTree.ToString());
}
}
in my CSHTML I do it like this
<div id="results">#Html.RenderXml(Model.theXmlFile, Model.theXSLFile,)</div>
When I try to return new HtmlString(newTree.ToString()); I get a blank, and when I try to return new HtmlString(writer.ToString()); I get this System.Xml.XmlWellFormedWriter on the page. Do anybody know what I am doing wrong? I got my code from the example here. I have also looked into this one and it works great except I do not use a URI, and when I try to modify it to use XDocument complains about missing parameters, so I stayed away from it. Any ideas why he transformation is not working?
Try moving the line return new HtmlString(newTree.ToString()); outside of the using block:
using (XmlWriter writer = newTree.CreateWriter())
{
// Load the style sheet.
XslCompiledTransform xslt = new XslCompiledTransform();
xslt.Load(XmlReader.Create(new StringReader(xsltPath)));
// Execute the transform and output the results to a writer.
xslt.Transform(xmlTree.CreateReader(), writer);
}
return new HtmlString(newTree.ToString());
I want to read only the xml used for generating equation, which i obtained by using Paragraph.Range.WordOpenXML. But the section used for the equation is not as per MathML which as i found that the Equation of microsoft is in MathML.
Do I need to use some special converter to get desired xmls or are there any other methods?
You could use the OMML2MML.XSL file (located under %ProgramFiles%\Microsoft Office\Office15)
to transform Microsoft Office MathML (equations) included in a word document into MathML.
The code below shows how to transform the equations in a word document into MathML
using the following steps:
Open the word document using OpenXML SDK (version 2.5).
Create a XslCompiledTransform and load the OMML2MML.XSL file.
Transform the word document by calling the Transform() method
on the created XslCompiledTransform instance.
Output the result of the transform (e.g. print on console or write to file).
I've tested the code below with a simple word document containing two equations, text and pictures.
using System.IO;
using System.Xml;
using System.Xml.Xsl;
using DocumentFormat.OpenXml.Packaging;
public string GetWordDocumentAsMathML(string docFilePath, string officeVersion = "14")
{
string officeML = string.Empty;
using (WordprocessingDocument doc = WordprocessingDocument.Open(docFilePath, false))
{
string wordDocXml = doc.MainDocumentPart.Document.OuterXml;
XslCompiledTransform xslTransform = new XslCompiledTransform();
// The OMML2MML.xsl file is located under
// %ProgramFiles%\Microsoft Office\Office15\
xslTransform.Load(#"c:\Program Files\Microsoft Office\Office" + officeVersion + #"\OMML2MML.XSL");
using (TextReader tr = new StringReader(wordDocXml))
{
// Load the xml of your main document part.
using (XmlReader reader = XmlReader.Create(tr))
{
using (MemoryStream ms = new MemoryStream())
{
XmlWriterSettings settings = xslTransform.OutputSettings.Clone();
// Configure xml writer to omit xml declaration.
settings.ConformanceLevel = ConformanceLevel.Fragment;
settings.OmitXmlDeclaration = true;
XmlWriter xw = XmlWriter.Create(ms, settings);
// Transform our OfficeMathML to MathML.
xslTransform.Transform(reader, xw);
ms.Seek(0, SeekOrigin.Begin);
using (StreamReader sr = new StreamReader(ms, Encoding.UTF8))
{
officeML = sr.ReadToEnd();
// Console.Out.WriteLine(officeML);
}
}
}
}
}
return officeML;
}
To convert only one single equation (and not the whole word document) just query for the desired Office Math Paragraph (m:oMathPara) and use the OuterXML property of this node.
The code below shows how to query for the first math paragraph:
string mathParagraphXml =
doc.MainDocumentPart.Document.Descendants<DocumentFormat.OpenXml.Math.Paragraph>().First().OuterXml;
Use the returned XML to feed the TextReader.
I have a "book.xml" and "book.xslt" the output has been set on text-mode, I don't want to load text file by browser because it is so heavy I need some code to save output text file in hard-drive. How I can implement this kind of transformation by c# ?
This should work:
XslCompiledTransform xslt = new XslCompiledTransform();
xslt.Load(#"c:\book.xslt");
xslt.Transform(#"c:\book.xml", #"c:\output.txt");
Obviously your paths will need to be updated to match your particular scenario, for example:
XslCompiledTransform xslt = new XslCompiledTransform();
xslt.Load(Server.MapPath("~/book.xslt"));
xslt.Transform(Server.MapPath("~/book.xml"), Server.MapPath("~/output.txt") );
This will read your XSL file from the root of the site and transform /book.xml and save it to /output.txt.
You can find out more about the System.Xml.Xsl.XslCompiledTransform class here:
System.Xml.Xsl.XslCompiledTransform
Use the System.Xml.Xsl.XslCompiledTransform class.
XslCompiledTransform transform = new XslCompiledTransform();
transform.Load(Server.MapPath("~/book.xslt"));
transform.Transform(Server.MapPath("~/book.xml"), Server.MapPath("~/output.xml"));
(Note: this assumed all the documents are stored in the root of the web application)
By using xmwwriter and xdocument like so:
using System.Data;
using System.Xml;
using System.Xml.XPath;
using System.Xml.Xsl;
public void xmltest(string xmlFilePath, string xslFilePath, string outFilePath)
{
var doc = new XPathDocument(xmlFilePath);
var writer = XmlWriter.Create(outFilePath);
var transform = new XslCompiledTransform();
// The following two lines are only needed if you need scripting.
// Because of security considerations read up on that topic on MSDN first.
var settings = new XsltSettings();
settings.EnableScript = true;
transform.Load(xslFilePath,settings,null);
transform.Transform(doc, writer);
}
More info here:
http://msdn.microsoft.com/en-us/library/14689742.aspx
regards
I was using this extension method to transform very large xml files with an xslt.
Unfortunately, I get an OutOfMemoryException on the source.ToString() line.
I realize there must be a better way, I'm just not sure what that would be?
public static XElement Transform(this XElement source, string xslPath, XsltArgumentList arguments)
{
var doc = new XmlDocument();
doc.LoadXml(source.ToString());
var xsl = new XslCompiledTransform();
xsl.Load(xslPath);
using (var swDocument = new StringWriter(System.Globalization.CultureInfo.InvariantCulture))
{
using (var xtw = new XmlTextWriter(swDocument))
{
xsl.Transform((doc.CreateNavigator()), arguments, xtw);
xtw.Flush();
return XElement.Parse(swDocument.ToString());
}
}
}
Thoughts? Solutions? Etc.
UPDATE:
Now that this is solved, I have issues with validating the schema!
Validating large Xml files
Try this:
using System.Xml.Linq;
using System.Xml.XPath;
using System.Xml.Xsl;
static class Extensions
{
public static XElement Transform(
this XElement source, string xslPath, XsltArgumentList arguments)
{
var xsl = new XslCompiledTransform();
xsl.Load(xslPath);
var result = new XDocument();
using (var writer = result.CreateWriter())
{
xsl.Transform(source.CreateNavigator(), arguments, writer);
}
return result.Root;
}
}
BTW, new XmlTextWriter() is deprecated as of .NET 2.0. Use XmlWriter.Create() instead. Same with new XmlTextReader() and XmlReader.Create().
For large XML files you can try to use XPathDocument as suggested in Microsoft Knowledge Base article.
XPathDocument srcDoc = new XPathDocument(srcFile);
XslCompiledTransform myXslTransform = new XslCompiledTransform();
myXslTransform.Load(xslFile);
using (XmlWriter destDoc = XmlWriter.Create(destFile))
{
myXslTransform.Transform(srcDoc, destDoc);
}