XSLT 结果文档抑制或替换不允许 windows 文件名字符

XSLT result-document supress or replace not allowed windows filename characters

我使用 xslt 3.0 输出几个带有结果文档的文件,但是 windows 文件名中有非法字符,例如 " 所以我尝试使用字符映射:

<xsl:character-map name="winfilename">
    <xsl:output-character character="&#34;" string="&#39;"/>
    <xsl:output-character character="&#58;" string="&#59;"/>
    <xsl:output-character character="&#60;" string="&#40;"/>
    <xsl:output-character character="&#62;" string="&#41;"/>
    <xsl:output-character character="&#47;" string="&#45;"/>
    <xsl:output-character character="&#92;" string="&#45;"/>
    <xsl:output-character character="&#63;" string="&#33;"/>
    <xsl:output-character character="&#94;" string="&#39;"/>
</xsl:character-map> 

但是当我使用 "use-character-maps" 和 "result-document" 时它不起作用。 怎么了?

编辑:这是开始的代码

<xsl:output method="text" encoding="UTF-8" indent="yes" use-character-maps="wf"/>
<xsl:mode name="start" streamable="yes"/>
<xsl:character-map name="wf">
    <xsl:output-character character="&#34;" string="&#39;"/>
    <xsl:output-character character="&#58;" string="&#59;"/>
    <xsl:output-character character="&#60;" string="&#40;"/>
    <xsl:output-character character="&#62;" string="&#41;"/>
    <xsl:output-character character="&#47;" string="&#45;"/>
    <xsl:output-character character="&#92;" string="&#45;"/>
    <xsl:output-character character="&#63;" string="&#33;"/>
    <xsl:output-character character="&#94;" string="&#39;"/>
</xsl:character-map>
<xsl:template match="/" mode="start">
    <xsl:apply-templates select="databank_export/copy-of(db_entry)" mode="entry"/>
</xsl:template>
<xsl:template match="db_entry">
    <xsl:result-document href="file:///E:\result\//{./public_data/sflname}.dat" method="text" encoding="UTF-8" use-character-maps="wf">
    <xsl:apply-templates select="public_data"/>
    </xsl:result-document>
</xsl:template>

这不起作用:错误 XTSE0350 未转义左大括号 我应该转义大括号吗?

<xsl:result-document href="file:///E:/result/{replace(./public_data/sflname,'[&quot;&lt;&gt;/\:?^]','[&apos;&#40;&#41;--;!-]')}.dat" method="text" encoding="UTF-8">

我想将数据库的每个条目输出到一个 "sflname".dat 文件。 我终于开始使用流式传输和序列化,但一些 sflname 字符串包含 windows 路径文件的无效字符,因此我想翻译它们以免失去可读性。但即使我按照你有 shawn 的例子。

<xsl:template match="db_entry">
    <xsl:result-document href="file:///E:/result/{translate(./public_data/sflname,'[&quot;&lt;&gt;&#47;&#92;&#58;&#63;&#94;]','[&apos;&#40;&#41;&#45;&#45;&#59;&#33;&#39;]')}.dat" method="text" encoding="UTF-8">
    <xsl:apply-templates select="public_data"/>
    </xsl:result-document>
</xsl:template>

我收到以下错误:

    Unexpected token ';!']')'
    Erreur d'emplacement : xsl:stylesheet / xsl:template / xsl:result-document / @href
    Détails
    XPST0003: The expression around 'sflname,'["<>/\:?^]','['()--;!']')' is not a valid instance of the XPath grammar

为什么?我应该删除方括号吗?有些字符需要双重转义吗?我是一个非常初学者,我不知道。根据 w3 xpath 参考和示例,它似乎是正确的。

此致

在结果树中序列化文本数据时将应用字符映射,而不是在使用文件名时。因此,您需要在构造文件名的地方使用 replace 函数,例如<xsl:result-document href="replace(url, '[list of characters here]', '')">。代码段中的 url 是一个示例元素名称,其中包含您的文件名以及要删除或替换的字符。

在您的代码片段中,您必须创建一个使用正斜杠的 URI,而不是

<xsl:result-document href="file:///E:\result\//{./public_data/sflname}.dat" method="text" encoding="UTF-8" use-character-maps="wf">

你需要

<xsl:result-document href="file:///E:/result/{public_data/sflname}.dat" method="text" encoding="UTF-8" use-character-maps="wf">

如果 public_data/sflname 可以包含您需要删除或替换的字符,则使用例如

<xsl:result-document href="file:///E:/result/{replace(public_data/sflname, '[list of characters]', '')}.dat" method="text" encoding="UTF-8" use-character-maps="wf">

如前所述,字符映射仅对您想对要创建的输出中的文本数据进行的任何替换有用,对文件名或 URI 没有帮助。

至于你最近使用 translate 的困难,使用 XML 和 XPath 的正确语法来引用带有 apostrophe/single 引号的字符串只是一个问题,那里与此相关的各种陷阱以及避免它们的各种方法,我建议定义两个全局参数

<xsl:param name="chars-to-be-replaced" as="xs:string">&quot;&lt;&gt;&#47;&#92;&#58;&#63;&#94;</xsl:param>
<xsl:param name="replacement-chars" as="xs:string">&apos;&#40;&#41;&#45;&#45;&#59;&#33;&#39;</xsl:param>

然后在你的翻译调用中你可以简单地使用

<xsl:result-document href="file:///E:/result/{translate(./public_data/sflname, $chars-to-be-replaced, $replacement-chars)}.dat" method="text" encoding="UTF-8">

当然,对于其中的大多数字符,实际上并不需要使用字符或实体引用,但我想这是基于您之前使用字符映射的方法,您可以将其写得更清楚,例如

<xsl:param name="chars-to-be-replaced" as="xs:string"><![CDATA["<>/\:?^]]></xsl:param>

分别

<xsl:param name="replacement-chars" as="xs:string">'()--;!'</xsl:param>