>背景:我正在开发一个XSLT来将XML文档转换为rtf文档。 XSLT 有一个名为 GetImageString 的 msxsl:script 函数,它返回给定图像文件的字符串表示形式,以便我可以将图像嵌入到 rtf 文档中。
问题:当 xslCompiledTransform 与 xmlWriterSettings 和 XmlWriter 一起使用时,转换的输出 (xsl:output method="text") 包括脚本函数的名称 (GetImageString) 以及 XSL 文件中包含的所有非默认命名空间的列表。 如果我在没有xmlWriterSettings和XmlWriter类的情况下使用XslCompiledTransform,则输出是正确的,除了在文件顶部插入BOM(字节顺序标记),这至少混淆了MS Word rtf阅读器。 因此,为了抑制 BOM,我必须使用 XmlWritterSettings(和 XmlWriter)类,但是在调用嵌入式 c# 代码时输出不正确。
这是我的xsl文件的一个片段:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xpp="http://www.sdl.com/xpp"
xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"
xmlns:v="urn:schemas-microsoft-com:vml"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
xmlns:rend="urn:rend-scripts">
<xsl:output method="text" encoding="utf-8"/>
<xsl:template match="xpp:document">
<xsl:text>{rtf1ansi {fonttbl </xsl:text>
<xsl:apply-templates select="//xpp:style"/>
<xsl:text> }</xsl:text>
<xsl:apply-templates select ="//xpp:image"/>
<xsl:text>};</xsl:text>
</xsl:template>
<msxsl:script language="c#" implements-prefix="rend">
<msxsl:assembly href="C:ProjectsLearningRTFSystem.IO.dll"/>
<msxsl:assembly href="C:ProjectsLearningRTFSystem.Drawing.dll"/>
<msxsl:using namespace="System.IO"/>
<msxsl:using namespace="System.Drawing"/>
<![CDATA[
public string GetImageString(string path_to_image){
MemoryStream stream = new MemoryStream();
Image img = Image.FromFile(path_to_image);
img.Save(stream, System.Drawing.Imaging.ImageFormat.Tiff);
byte[] bytes = stream.ToArray();
string output = BitConverter.ToString(bytes, 0).Replace("-", string.Empty);
return output;
}
]]>
</msxsl:script>
<xsl:template match="xpp:image">
<xsl:text>
{pictwmetafile8</xsl:text>
<GetImageString>
<xsl:text> </xsl:text>
<xsl:value-of select="rend:GetImageString(@path)"/>
</GetImageString>
<xsl:text>}</xsl:text>
</xsl:template>
下面是调用转换的 c# 程序:
public void TransformWithMS()
{
XsltSettings xsltConfig = new XsltSettings(false,true);
XslCompiledTransform xslt = new XslCompiledTransform();
xslt.Load("scratch.xsl",xsltConfig,null);
//xslt.Transform("divxml_modified.xml", "scratch.rtf");
XmlWriterSettings xmlWriterSettings = new XmlWriterSettings();
xmlWriterSettings.Encoding = new UTF8Encoding(false);
xmlWriterSettings.ConformanceLevel = ConformanceLevel.Auto;
XmlWriter results = XmlWriter.Create("scratch.rtf", xmlWriterSettings);
xslt.Transform("divxml_modified.xml", results);
}
这是有问题的输出的样子:
{\rtf1\ansi {\fonttbl {\f1 Times New Roman;}} {\pict\wmetafile8 GetImageString xmlns:xpp="http://www.sdl.com/xpp">xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">xmlns:v="urn:schemas-microsoft-com:vml" xmlns:msxsl="urn:schemas-microsoft-com:xslt">xmlns:rend="urn:rend-scripts" 49492A00BC480000803...
(GetImageString 和 namepcaes 列表周围有一个<和一个>,但我很难弄清楚如何将其格式化为问题)和一个>
有人知道如何在没有输出函数名称和额外命名空间(并且没有 BOM)的情况下调用 msxsl:script 函数?
如果要更改 .NET 代码输出的设置,则应使用
XmlWriterSettings myOutputSettings = xslt.OutputSettings.Clone();
myOutputSettings.Encoding = new UTF8Encoding(false);
现在创建一个 XmlWriter,例如
using (XmlWriter result = XmlWriter.Create("scratch.rtf", myOutputSettings))
{
xslt.Transform("divxml_modified.xml", result);
}
这允许您拥有一个 XmlWriter,它根据xsl:output
输出,但编码已更改。
我不确定这是否可以解决输出中出现的代码的问题,请尝试报告。