1

(将问题从“静态替换”更新为“动态替换”)

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

文本的结果应该是“你好唐老鸭”。</p>


添加:

我认为部分问题可以用 解决<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,这不会按照我想要的方式工作。

4

1 回答 1

2

我不知道您在尝试什么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".

于 2022-02-09T12:45:43.550 回答