多个字符串替换
Multiple string replacements
(将问题从 'static replace' 更新为 'dynamic replace')
<data>
<replacements>
<replace key="greeting" value='Hello' />
<replace key="name" value='Donald' />
</replacements>
<rules>
<rule key="GREETING" value="replacements/replace[@key='greeting']/@value" />
<rule key="NAME" value="replacements/replace[@key='name']/@value" />
</rules>
<text>
GREETING NAME duck.
</text>
</data>
我想用所有规则中每次出现的键替换元素 text
中的文本。替换文本是对该元素中属性 value
的评估。
我应该采用哪种方法(使用最新的 Saxon HE)?
文本的结果应该是“你好唐老鸭”。
加法:
我认为部分问题可以用 <xsl:evaluate>
解决,但这显然还行不通(没有字符串替换):
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="3.0" >
<xsl:output indent="yes"/>
<xsl:template match="data">
<xsl:copy>
<xsl:evaluate xpath="/data/rules/rule[1]/@value" context-item="." />
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
结果是<data value="Hello"/>
。我看到的是 xpath 表达式的动态评估,从那里应该可以进行字符串替换。
现在我的步骤是将我的方法添加到 Martin 的回答中,但这将在 XPath 中混合 XSLT,这不是我想要的方式。
我不知道你在用 xsl:evaluate
做什么,如果你提到它,考虑显示你的代码,但似乎 fold-left
调用 replace
就足够了:
<xsl:template match="text" expand-text="yes">
<xsl:copy>{fold-left(../rules/rule, ., function($a, $r) { replace($a, $r/@key, $r/@value) })}</xsl:copy>
</xsl:template>
<xsl:template match="data/rules"/>
您可以使用更复杂的“替换规则和数据”结构
<xsl:function name="mf:evaluate-value">
<xsl:param name="rule" as="element(rule)"/>
<xsl:evaluate context-item="$rule/../.." xpath="$rule/@value"/>
</xsl:function>
<xsl:template match="text" expand-text="yes">
<xsl:copy>{fold-left(../rules/rule, ., function($a, $r) { replace($a, $r/@key, mf:evaluate-value($r)) })}</xsl:copy>
</xsl:template>
<xsl:template match="data/rules | data/replacements"/>
对于 use 函数,您需要在样式表中声明一个名称空间,例如xmlns:mf="http://example.com/mf"
.
(将问题从 'static replace' 更新为 'dynamic replace')
<data>
<replacements>
<replace key="greeting" value='Hello' />
<replace key="name" value='Donald' />
</replacements>
<rules>
<rule key="GREETING" value="replacements/replace[@key='greeting']/@value" />
<rule key="NAME" value="replacements/replace[@key='name']/@value" />
</rules>
<text>
GREETING NAME duck.
</text>
</data>
我想用所有规则中每次出现的键替换元素 text
中的文本。替换文本是对该元素中属性 value
的评估。
我应该采用哪种方法(使用最新的 Saxon HE)?
文本的结果应该是“你好唐老鸭”。
加法:
我认为部分问题可以用 <xsl:evaluate>
解决,但这显然还行不通(没有字符串替换):
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="3.0" >
<xsl:output indent="yes"/>
<xsl:template match="data">
<xsl:copy>
<xsl:evaluate xpath="/data/rules/rule[1]/@value" context-item="." />
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
结果是<data value="Hello"/>
。我看到的是 xpath 表达式的动态评估,从那里应该可以进行字符串替换。
现在我的步骤是将我的方法添加到 Martin 的回答中,但这将在 XPath 中混合 XSLT,这不是我想要的方式。
我不知道你在用 xsl:evaluate
做什么,如果你提到它,考虑显示你的代码,但似乎 fold-left
调用 replace
就足够了:
<xsl:template match="text" expand-text="yes">
<xsl:copy>{fold-left(../rules/rule, ., function($a, $r) { replace($a, $r/@key, $r/@value) })}</xsl:copy>
</xsl:template>
<xsl:template match="data/rules"/>
您可以使用更复杂的“替换规则和数据”结构
<xsl:function name="mf:evaluate-value">
<xsl:param name="rule" as="element(rule)"/>
<xsl:evaluate context-item="$rule/../.." xpath="$rule/@value"/>
</xsl:function>
<xsl:template match="text" expand-text="yes">
<xsl:copy>{fold-left(../rules/rule, ., function($a, $r) { replace($a, $r/@key, mf:evaluate-value($r)) })}</xsl:copy>
</xsl:template>
<xsl:template match="data/rules | data/replacements"/>
对于 use 函数,您需要在样式表中声明一个名称空间,例如xmlns:mf="http://example.com/mf"
.