Asked  7 Months ago    Answers:  5   Viewed   23 times

I want to apply an XSLT Stylesheet to an XML Document using C# and write the output to a File.

 Answers

83

I found a possible answer here: http://web.archive.org/web/20130329123237/http://www.csharpfriends.com/Articles/getArticle.aspx?articleID=63

From the article:

XPathDocument myXPathDoc = new XPathDocument(myXmlFile) ;
XslTransform myXslTrans = new XslTransform() ;
myXslTrans.Load(myStyleSheet);
XmlTextWriter myWriter = new XmlTextWriter("result.html",null) ;
myXslTrans.Transform(myXPathDoc,null,myWriter) ;

Edit:

But my trusty compiler says, XslTransform is obsolete: Use XslCompiledTransform instead:

XPathDocument myXPathDoc = new XPathDocument(myXmlFile) ;
XslCompiledTransform myXslTrans = new XslCompiledTransform();
myXslTrans.Load(myStyleSheet);
XmlTextWriter myWriter = new XmlTextWriter("result.html",null);
myXslTrans.Transform(myXPathDoc,null,myWriter);
Tuesday, June 1, 2021
 
VieStar
answered 7 Months ago
91

XSLT uses XPath and this requires that the whole XML document be maintained in memory. Thus the problem of insufficient memory is by definition.

There are simle rules to approximate how much memory is needed and one of them says 5 * text-size.

So, for a "typical 1.5GB XML file" 8GB RAM may be sufficient.

Either split the document into smaller parts or wait for an implementation of XSLT 2.1, which defines special streaming instructions. In the meantime one may use the latest (commercial) version of Saxon, which implements extensions for streaming and successful processing of 64GB document has been reported on twitter.

Tuesday, July 6, 2021
 
Avicinnian
answered 5 Months ago
14

The StringReader -> XmlReader approach is fine, you should stick to it. The reader reports none because it hasn't been read yet. Try calling Read() on it to see what happens then. The transformation will also call read on it.

Monday, August 9, 2021
 
Mirko
answered 4 Months ago
21

Say you have a Player class that looks like:

[XmlRoot]
public class Player
{
    [XmlElement]
    public int Level { get; set; }

    [XmlElement]
    public int Health { get; set; }
}

Here is a complete round-trip to get you started:

XmlSerializer xmls = new XmlSerializer(typeof(Player));

StringWriter sw = new StringWriter();
xmls.Serialize(sw, new Player { Level = 5, Health = 500 });
string xml = sw.ToString();

Player player = xmls.Deserialize(new StringReader(xml)) as Player;

xml is:

<?xml version="1.0" encoding="utf-16"?>
<Player xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Level>5</Level>
  <Health>500</Health>
</Player>

And you guess player is exactly the same as the original object we serialized.

If you want to serialize to/deserialize from files you can do something like:

using (var stream = File.OpenWrite("my_player.xml"))
{
    xmls.Serialize(stream, new Player { Level = 5, Health = 500 });
}

Player player = null;
using (var stream = File.OpenRead("my_player.xml"))
{
    player = xmls.Deserialize(stream) as Player;
}

EDIT:

IF you want exactly the XML you show:

XmlSerializer xmls = new XmlSerializer(typeof(Player));

XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
ns.Add("", "");
XmlWriterSettings settings = new XmlWriterSettings { OmitXmlDeclaration = true, Indent = true };
using (var stream = File.OpenWrite("my_player.xml"))
{
    using (var xmlWriter = XmlWriter.Create(stream, settings))
    {
        xmls.Serialize(xmlWriter, new Player { Level = 5, Health = 500 }, ns);
    }
}

Player player = null;
using (var stream = File.OpenRead("my_player.xml"))
{
    player = xmls.Deserialize(stream) as Player;
}
Tuesday, August 10, 2021
 
Philippe Hebert
answered 4 Months ago
39

You can embedd it in your assembly.

Add the file in your solution, set the build action to embedded resource.

The place you need to read the file use http://msdn.microsoft.com/en-us/library/xc4235zt.aspx Assembly.GetManifestResourceStream wich will give you a stream wich you can write to a fil or use directly.

If you are not quite sure what name your resource have, I find Assembly.GetManifestResourceNames usefull to list all resources.

Tuesday, September 21, 2021
 
Marcus Junius Brutus
answered 3 Months ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :
 
Share