【问题标题】:XSLT result-document supress or replace not allowed windows filename charactersXSLT 结果文档抑制或替换不允许的 Windows 文件名字符
【发布时间】:2025-12-06 12:35:01
【问题描述】:

我使用 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 路径文件的无效字符,所以我想翻译它们以免失去可读性。但即使我按照你肖恩的例子。

<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 refs 和示例,这似乎是正确的。

最好的问候

【问题讨论】:

  • 你为什么不简单地使用translate()函数?
  • 不清楚你想用你最近的replace 尝试实现什么,通常第二个字符串是替换字符串,而不是替换字符列表。因此,如前所述,translate 可能是一个更好的工具,如果您想用另一个字符串中的相应字符替换字符串中的每个字符。见w3.org/TR/xpath-functions-31/#func-replacew3.org/TR/xpath-functions-31/#func-translate
  • 我想将数据库的每个条目输出到“sflname”.dat 文件。我终于让流和序列化工作了,但是一些 sflname 字符串包含 Windows 路径文件的无效字符,所以我想翻译它们以免失去可读性。
  • 查看我对如何在字符串中安全使用单引号的一种方法的回答的编辑。

标签: xml xslt saxon


【解决方案1】:

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

在您的代码 sn-p 中,您必须创建一个使用正斜杠的 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 语法来引用带有撇号/单引号的字符串只是一个问题,与此相关的各种陷阱和各种方法避免它们,我建议定义两个全局参数

<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>

【讨论】:

  • 所以这是关于 '我猜的实体。但这不适用于带有数据库的 saxonEE。程序运行但没有写入文件,然后程序结束,没有错误消息。 XMLspy 使用 36 个小型条目 db。
  • 确保使用 -t 选项运行 Saxon 以查看/检查将哪些文件写入哪个位置。如果您仍有问题,请发布最少但完整的示例,以便我们重现问题。
  • 很抱歉让您耽误了时间。对不起。路径中的某个单词在某处丢失并且无法正常工作。