Doing something like this:
using (XmlWriter myMamlHelpWriter = XmlWriter.Create(myFileStream, XmlHelpExToMamlXslTransform.OutputSettings))
{
XmlHelpExToMamlXslTransform.Transform(myMsHelpExTopicFilePath, null, myMamlHelpWriter);
}
where
private static XslCompiledTransform XmlHelpExToMamlXslTransform
{
get
{
if (fMsHelpExToMamlXslTransform == null)
{
// Create the XslCompiledTransform and load the stylesheet.
fMsHelpExToMamlXslTransform = new XslCompiledTransform();
using (Stream myStream = typeof(XmlHelpBuilder).Assembly.GetManifestResourceStream(
typeof(XmlHelpBuilder),
MamlXmlTopicConsts.cMsHelpExToMamlTransformationResourceName))
{
XmlTextReader myReader = new XmlTextReader(myStream);
fMsHelpExToMamlXslTransform.Load(myReader, null, null);
}
}
return fMsHelpExToMamlXslTransform;
}
}
And every time the string “"” is replaced with real quotes in the result file.
Cannot understand why this happens…
The reason is that in the XSLT’s internal representation,
"is exactly the same characer as". They both represent the ascii code point 0x34. It would seem that when the XslCompiledTransform produces its output, it uses"where it’s legal to do so. I would imagine that it would still output"inside an attribute value.Is it a problem for you that
"is produced as"in the output?I just ran the following XSLT in Visual Studio using an arbitrary input file:
The output was:
As you can see, even though all five characters were represented as entities originally, the apostrophies are produced as
'everywhere, and quotation marks are produced as"in text nodes. Furthermore, theaattribute which had'delimiters uses"delimiters in the output. As I said, as far as the XSLT cares, a quotation mark is just a quotation mark, and an attribute is just an attribute. How those are produced in the output is up to the XSLT processor.Edit: The root cause of this behavior appears to be the behavior of the XmlWriter class. It looks like the general suggestion for those who want more customized escaping is to extend the
XmlTextWriterclass. This page has an implementation that looks fairly promising:On the other hand, the MSDN documentation recommends using
XmlWriter.Create()rather than instantiating XmlTextWriters directly.One way around that would be to use the same logic as above, but put it in a class that wraps an
XmlWriter. This page has a ready-made implementation of an XmlWrappingWriter, that you can modify as needed.To use the above code with the
XmlWrappingWriter, you would subclass the wrapping writer, like this:Note this essentially the same code as the
KeepEntityXmlTextWriter, but using XmlWrappingWriter as the base class and with a different constructor.I don’t recognize the
Guardthat theXmlWrappingWritercode is using in two places, but given that you’ll be consuming the code yourself, it should be pretty safe to delete the lines like this. They just ensure that a null value isn’t passed to the constructor or the (in the above case inaccessible)BaseWriterproperty:To create an instance of the
XmlWrappingWriter, you would create an XmlWriter however you need to, and then use:And then you’d use this
wrapvariable as the XmlWriter you pass to your XSL transform.