.NET 5.0 中的 xslt PDF 转换:特殊字符问题

Posted

技术标签:

【中文标题】.NET 5.0 中的 xslt PDF 转换:特殊字符问题【英文标题】:xslt PDF transformation in .NET 5.0: problem with special character 【发布时间】:2021-10-02 04:07:15 【问题描述】:

在将 XSLT 转换为 PDF 时,我遇到了特殊“外来”字符的问题。这是我在 C# 中的代码:

XDocument xmlDoc = XDocument.Load("myXml.xml");
XDocument xslt = XDocument.Load("myXSL.xsl");
XsltArgumentList args = new XsltArgumentList();

string str = XmlLinqXsltExtensions.Transform(xmlDoc, xslt, args);
File.WriteAllText("foStr.xml",str);

XslFOPdfOptions xslFoPdfOptions = new XslFOPdfOptions();
xslFoPdfOptions.EnablePrinting = true;

FONetXslFOPdfRenderer foNetXslFoPdfRenderer = new FONetXslFOPdfRenderer(XDocument.Load(("foStr.xml"), xslFoPdfOptions);
byte[] bytes = foNetXslFoPdfRenderer.RenderPdfBytes();
outputStream.Write(bytes, 0, bytes.Length);      // bytes contain the PDF

“myXml.xml”采用 UTF-8 格式。它包含一些特殊字符,如“ć”和其他:

样式表“myXSL.xsl”确实包含编码信息:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.1" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:fo="http://www.w3.org/1999/XSL/Format">

    <xsl:output method="xml" encoding="utf-8" indent="yes"/>

中间“foStr.xml”的输出是正确的:

“foStr.xml”编码也是UTF-8。

尽管如此,在 PDF 中,我在输出中得到了替换字符 #:

#ebi-Ili# #nn#

问题:

知道如何让 FONetXslFOPdfRenderer 生成正确的字符吗?

nuget 包的版本:

PdfTemplating.XslFO.Common: 2.1.0 PdfTemplating.XslFO.Xslt: 2.0.0

【问题讨论】:

代码string str = XmlLinqXsltExtensions.Transform(xmlDoc, xslt, args);到底是做什么的?字符串str 是否带有在开头声明的编码的 XML 声明? File.WriteAllText("foStr.xml",str); 是否确保使用声明的编码写入文件? 我们真的需要看看你的方法XmlLinqXsltExtensions.Transform的代码。我的猜测是字符串返回的编码与File.WriteAllText 方法使用的默认UTF-8 编码之间存在不匹配。这样XDocument.Load(("foStr.xml") 就无法正确解码字符。 字符串“str”包含生成 PDF 所需的 fo 数据。它的开头也有编码标记: XmlLinqXsltExtensions 是 NuGet 包 PdfTemplating.XslFO.Xslt 的一部分。 所以它看起来更像是那个 PDF 渲染器的字体设置问题。不知道那个包是怎么做的,看看你是否可以找到一些选项来确保它使用可以呈现非 ASCII 字符的字体。 【参考方案1】:

在 Martin Honnen 提出 font-family="Arial" 之后,答案其实就是选择一个对特殊字符支持足够大的字体家族。

你可以做例如这个:

<xsl:template match="/">
    <fo:root xsl:use-attribute-sets="text-attributes">
...

<xsl:attribute-set name="text-attributes">
    <xsl:attribute name="font-family">Arial</xsl:attribute>
</xsl:attribute-set>

这将是问题的一般解决方案。

【讨论】:

以上是关于.NET 5.0 中的 xslt PDF 转换:特殊字符问题的主要内容,如果未能解决你的问题,请参考以下文章

将命名空间从 java 传递给 xslt,并使用 java 中的参数作为 xslt 中的节点

是否有可用于将 WordprocessingML 转换为 RTF 的 XSLT

Adobe LiveCycle:使用 XSLT 将 XML 转换为 XML

.Net Core XSLT 转换引发异常“无效的 XML 字符”。但在 .Net Framework 上工作正常

C# 将 Saxon XSLT 转换结果显示到当前 ASP.NET 容器页面

XSLT 转换输出仅显示第一页并且图形被截断