XSLT结果文档supress或replace不允许使用Windows文件名字符

时间:2017-08-14 04:02:45

标签: xml xslt saxon

我使用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> 

但是当我使用&#34; use-character-maps&#34;时,它不起作用。用&#34;结果文件&#34;。 怎么了?

编辑:这是代码开始

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

我想将数据库的每个条目输出到&#34; sflname&#34; .dat文件。 我终于得到流和序列化工作,但一些sflname字符串包含invalids char for windows pathfile所以我想翻译它们,以免失去可读性。但是,即使我按照你的例子你也是如此。

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

祝你好运

1 个答案:

答案 0 :(得分:1)

在结果树中序列化文本数据时将应用字符映射,而不是在使用文件名时。因此,您需要使用构建文件名的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的正确语法引用内部带有撇号/单引号的字符串只是一个问题,存在与此相关的各种陷阱如何避免它们,我建议定义两个全局参数

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