0

我有一个想要复制的 XML 文档,但我不知道如何翻译一个特殊属性。复制 XML 并替换 gernal 中的属性可以正常工作,但我不知道如何在 XSL 中定义一个短语列表,然后将其翻译成另一个短语。

定义应该易于阅读。会translate()吞下某种列表表示吗?一个使用的小例子translate会很棒(不要关心 XML 复制的东西)。

4

1 回答 1

1

XPath 和 XSLT 1.0的translate功能仅用于将一个 Unicode 字符替换为另一个 Unicode 字符;您可以提供输入和替换字符的列表,然后第一个列表中的每个字符将被第二个列表中相同位置的字符替换。但是要替换完整的作品或短语,您需要其他工具。

您没有说或描述是否要替换完整的属性值,假设您可以(使用 XSLT 2.0)简单地执行例如

<xsl:stylesheet
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  version="2.0">

<xsl:key name="phrase" match="phrase" use="@input"/>

<xsl:param name="phrases">
  <phrases>
    <phrase input="IANAL" output="I am not a lawyer"/>
    <phrase input="WYSIWYG" output="What you see is what you get"/>
  </phrases>
</xsl:param>

<xsl:template match="@* | node()">
  <xsl:copy>
    <xsl:apply-templates select="@* , node()"/>
  </xsl:copy>
</xsl:template>


<xsl:template match="foo/@bar">
  <xsl:attribute name="baz" select="key('phrase', ., $phrases)/@output"/>
</xsl:template>

</xsl:stylesheet>

例如,该样式表转换

<root>
  <foo bar="IANAL"/>
  <foo bar="WYSIWYG"/>
</root>

进入

<root>
  <foo baz="I am not a lawyer"/>
  <foo baz="What you see is what you get"/>
</root>

如果您想对一个值或字符串中的子字符串进行多次替换,则需要付出更多的努力,但使用replaceXSLT/XPath 2.0 中的函数也是可能的。

[编辑]这是一个使用项目列表和递归函数替换短语的示例:

<xsl:stylesheet
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  xmlns:mf="http://example.com/mf"
  exclude-result-prefixes="xs mf"
  version="2.0">

<xsl:key name="phrase" match="phrase" use="@input"/>

<xsl:function name="mf:replace-phrases" as="xs:string">
  <xsl:param name="phrases" as="element(phrase)*"/>
  <xsl:param name="text" as="xs:string"/>
  <xsl:choose>
    <xsl:when test="not($phrases)">
      <xsl:sequence select="$text"/>
    </xsl:when>
    <xsl:otherwise>
      <xsl:sequence select="mf:replace-phrases($phrases[position() gt 1], replace($text, $phrases[1]/@input, $phrases[1]/@output))"/>
    </xsl:otherwise>
  </xsl:choose>
</xsl:function>

<xsl:param name="phrases">
  <phrases>
    <phrase input="IANAL" output="I am not a lawyer"/>
    <phrase input="WYSIWYG" output="What you see is what you get"/>
  </phrases>
</xsl:param>

<xsl:template match="@* | node()">
  <xsl:copy>
    <xsl:apply-templates select="@* , node()"/>
  </xsl:copy>
</xsl:template>


<xsl:template match="foo/@bar">
  <xsl:attribute name="baz" select="mf:replace-phrases($phrases/phrases/phrase, .)"/>
</xsl:template>

</xsl:stylesheet>

这改变了例子

<root>
  <foo bar="He said: 'IANAL'. I responded: 'WYSIWYG', and he smiled."/>
</root>

进入

<root>
  <foo baz="He said: 'I am not a lawyer'. I responded: 'What you see is what you get', and he smiled."/>
</root>
于 2012-12-18T18:26:36.793 回答