【问题标题】:XSLT 1.0 Translate String - Change Character to New LineXSLT 1.0 翻译字符串 - 将字符更改为新行
【发布时间】:2016-06-21 16:36:49
【问题描述】:

我希望这是一个简单的,虽然它似乎往往不是......

我正在使用 XLST 1.0,我有一个字符串,我需要 translate。此字符串是用户输入的文本字段。它包含几个由分隔符分隔的较小字符串。 (在这种情况下,它是“|”。)这个字符串的长度和特殊字符的数量变化很大。

(此字段类似于 CSV 列表,但不是使用逗号作为分隔符,而是使用“|”作为分隔符。)

我需要学习如何将此分隔符更改为<br>

我已尝试使用以下 XSL 来实现此目的:

<xsl:variable name="stringtotrans">
    <xsl:text>String1|String2|String3</xsl:text>
</xsl:vairable>
    <!-- In the actual XML document, this variable grabs the value of an attribute. -->
    <!-- For this example, it's being entered manually. -->
    <!-- The number and length of the individual strings varies widely. -->

<xsl:value-of select="translate($stringtotrans, '|', '&#xA;&#xD;')"/>

当这段代码运行时,输出为:

String1String2String3

预期/期望的输出是:

String1
String2
String3

我们将不胜感激任何和所有的帮助!

【问题讨论】:

  • translate() 函数可以将一个字符转换为另一个字符。它不能将一个字符转换为两个或多个字符的字符串,也不能转换为诸如&lt;br&gt; 之类的元素。为此,您需要一个递归模板,如下所示:stackoverflow.com/questions/30339128/…
  • 哦,太好了.../sarc 我会检查这个例子,看看我是否能解决这个问题。同时,有没有其他方法可以达到预期的效果?
  • 有没有其他方法可以达到预期的效果?” XSLT 1.0 中没有。如果您的 XSLT 1.0 处理器支持 EXSLT str:tokenize() 扩展功能,那么它会更容易一些。 --附言您还没有确切地告诉我们您的“期望结果”是什么。 -- PP.S.你的讽刺错位了。
  • 迈克尔,我不确定我是否理解你(在任何方面)。所需的结果如上所示。分隔列表中的每个子字符串,带有“|”分隔符,应该出现在它自己的行上。至于/sarc,这是指translate 函数无法执行任何重要价值的翻译,唯一明显的替代方案是更复杂和复杂的解决方案。这绝不是贬低您的回应,也不是针对您的。
  • "所需的结果如上所示。" 你说:“将此分隔符更改为换行符、
    或其他此类字符。
    ”这很模棱两可。如果您的结果是文本,那么newline 可以表示 CR (Mac)、LF (Unix) 或 CRLF (Windows)。前两个是单个字符,因此 可以translate() 生成。最后一个不是,也不能。如果您的结果是 HTML,那么您需要 &lt;br&gt;。那不是一个字符,当然它不能被translate() 函数返回。鉴于这样的差异,你会明白“other such character”是没有意义的。

标签: xml xslt special-characters newline character-replacement


【解决方案1】:

我需要学习如何将此分隔符更改为&lt;br&gt;

以下样式表:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" encoding="UTF-8" />

<xsl:template match="/">

    <xsl:variable name="stringtotrans">
        <xsl:text>String1|String2|String3</xsl:text>
    </xsl:variable>

    <p>
        <xsl:call-template name="tokenize">
            <xsl:with-param name="text" select="$stringtotrans"/>
        </xsl:call-template>
    </p>
</xsl:template>

<xsl:template name="tokenize">
    <xsl:param name="text"/>
    <xsl:param name="delimiter" select="'|'"/>
    <xsl:choose>
        <xsl:when test="contains($text, $delimiter)">
            <xsl:value-of select="substring-before($text, $delimiter)"/>
            <br/>
            <!-- recursive call -->
            <xsl:call-template name="tokenize">
                <xsl:with-param name="text" select="substring-after($text, $delimiter)"/>
            </xsl:call-template>
        </xsl:when>
        <xsl:otherwise>
            <xsl:value-of select="$text"/>
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>

</xsl:stylesheet>

应用于任何 XML 输入,将返回:

<p>String1<br>String2<br>String3</p>

【讨论】:

  • 谢谢。这个解决方案效果很好!再次感谢您的帮助和解释。
【解决方案2】:

translate() 函数从一个字符映射到另一个字符。在您的情况下,您将| 替换为&amp;#xA;(第一个字符),即换行符(LF)。这可能适用于 LF 通常标记行尾的 Unix 系统,但不适用于 Windows,例如,行尾标记为 CR+LF (&amp;#xD;&amp;#xA;)。

有关 XML 中 EOL 的更多详细信息,请参阅How to add a newline (line break) in XML file?

有关在 XSLT 1.0 中用字符串替换字符,请参阅Michael's recursive template for replace

【讨论】:

  • 我已尝试实现递归模板,但遇到了一个重大问题。当我实现它时,输出完全是空白的。 (甚至从以前工作的 XSL 中删除其余的输出。)有什么想法?
  • 您需要提供更多关于它是如何失败的信息(请在一个新问题中,而不是评论),但是Michael's answer here to your specific question 有什么问题?
  • 我不确定它为什么不起作用。我可能只是打错了字。迈克尔的解决方案正在奏效。谢谢你们的帮助和解释!
猜你喜欢
  • 2021-10-10
  • 2017-03-11
  • 1970-01-01
  • 2023-03-23
  • 1970-01-01
  • 1970-01-01
  • 2011-11-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多