XSL list of words to replace, most easy defintion

2019-08-16 05:38发布

问题:

I've got a XML document that I want to cop<, but I don't know how to translate one special attribute. Copying the XML and replacing the attribute in gernal works fine, but I don't know how I can define a list of phrases in XSL that are then translated into another phrase.

The definition should be easyly readable. Does translate() swallow some kind of list representation? A small example using translate would be great (don't care about the XML copying stuff).

回答1:

The translate function of XPath and XSLT 1.0 serves only to replace one Unicode character by another Unicode character; you can provide a list of input and replacement characters where then each character in the first list is then replaced by the one in the second list at the same position. But to replace complete works or phrases you need other tools.

You have not said or described whether you want to replace the complete attribute value, assuming that you can (with XSLT 2.0) simply do e.g.

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

That stylesheet transforms for instance

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

into

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

If you want to do several replacements of substrings in one value or string then more effort is needed but with the replace function in XSLT/XPath 2.0 that is possible too.

[edit]Here is an example using a list of items and a recursive function replacing phrases:

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

That transforms the example

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

into

<root>
  <foo baz="He said: 'I am not a lawyer'. I responded: 'What you see is what you get', and he smiled."/>
</root>