【问题标题】:Use ends with in XSLT v1.0在 XSLT v1.0 中使用以结尾
【发布时间】:2025-12-05 06:35:01
【问题描述】:

我正在尝试编辑当前的 XSLT。我想要的功能是当“//code_no”的值以 01 结尾时,我想编辑当前城市位置。目前此功能不存在。 我曾尝试使用字符串和子字符串,但它给了我一个错误,说以功能结尾不存在。请帮忙

来自xml的值是

<code_no>
1870410001
</code_no>

在 xsl 中,我想在值以 01 结尾时打印它。

<td align="left" width="33%"><SPAN style="font-size: 12pt; font-family: Arial;">
    <a> <b><u><xsl:value-of select="//city"/>, <xsl:value-of select="//state"/> 
    </u></b></a></SPAN></td>

【问题讨论】:

  • 说真的,帮助我们帮助你。您尚未发布您的输入 XML 或所需的输出,因此无法回答。
  • 目前我正在使用 获取代码 no 的值现在我想使用这个代码 no 如果这个代码没有以01,我想把默认值改成别的东西
  • 我的意思是我们需要查看您的输入 XML 和所需的输出。请编辑问题以包含此内容。如果您不确定应该发布哪种代码,请参阅其他 XSLT 问题。

标签: xml xslt


【解决方案1】:

(XPath 2.0)表达式的 XPath 1.0 等效项:

ends-with($s, $t)

$t = substring($s, string-length($s) - string-length($t) +1)

您只需将最后一个 XPath 表达式中的$s$t 分别替换为要测试的字符串和要测试的结尾。

这是一个完整的例子

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:template match="x|y">
     <xsl:value-of select="name()"/> ends-with '_01': <xsl:value-of select=
     "'_01' = substring(., string-length() - 2)"/>
=============   
 </xsl:template>
</xsl:stylesheet>

当此转换应用于以下 XML 文档时(问题中未提供任何内容!!!):

<t>
 <x>abcd_01</x>
 <y>abcd_11</y>
</t>

产生了想要的正确结果:

x ends-with '_01': true
=============   
 y ends-with '_01': false
=============   

【讨论】:

  • 在我的机器上,以下错误: $t = substring($s, string-length() - string-length($t) +1) 源字符串需要是参数第一个字符串长度调用。所以这有效: $t = substring($s, string-length($s) - string-length($t) +1)
  • @FrederikSchøning:是的,答案中的表达式假定 $s 是上下文节点(或上下文项)的字符串值。我会尽快纠正这个问题。
  • 现在差不多了 - 只需要括号中的 '$s' 而不是 's' :)
【解决方案2】:

我用过

contains($string, $part) and normalize-space(substring-after($string, $part)) = ''

在哪里

我们正在检查 $string 是否以 $part 结尾

【讨论】:

  • "我们正在检查 $string 是否以 $part 结尾" 并非如此。您正在检查 $string 是否以 $part 结尾或 $string 不包含 $part。当 $string = "abc" 和 $part ="d" 你的测试返回一个误报。
  • @michael.hor257k 你是对的。只是为了更正它而编辑。感谢您为我保存了一个错误。干杯:)
  • 这看起来好多了 - 我相信您可以将其缩短为:contains($string, $part) and not(substring-after($string, $part))。另见:*.com/questions/21828498/…
  • 如果 $part 多次出现在 $string 中,您会得到误报
【解决方案3】:

XSLT 1.0 使用XPath 1.0,它不包括任何名为ends-with 的函数。您可以使用此处找到的技术来伪造它:

【讨论】:

  • 我尝试使用 但它给出了错误
  • 预期的令牌 '$' 找到了 'NAME'。 substring(-->$code
  • @user1582320:您还没有向我们展示您的输入 XML。我们见过.//code_no@code_no$code_no。实际输入的 XML 是什么样的???
  • 来自 xml 的实际输入是 324253452345 仅此而已,我没有什么可以给你的
  • 好的,我明白了...我使用了子字符串并处理了它。问题是他们最初使用 xmlns:start-date="urn:schemas-microsoft-com:datatypes"> 这几乎与任何东西都不兼容。所以无论如何谢谢。
【解决方案4】:

我知道这个问题实际上是一个老问题,但现在我正在寻找同样的问题。

不过,最后我想出了一些其他的东西,将来可能会被别人使用。

请看这个:

contains(concat($str1, '$'), concat($str2, '$'))

快速、简单、无需计算。

使用示例:

    <xsl:variable name="str1" select="string('Some text to test.')" />
    <xsl:variable name="str2" select="string('test.')" />

    <xsl:if test="contains(concat($str1, '$'), concat($str2, '$'))">
        <xsl:value-of select="concat('Yes, text: &quot;', $str1, '&quot; ends with: &quot;', $str2, '&quot;.')"/>
    </xsl:if>

当然你可以使用任何符号代替 $ 来表示 concat() 函数。

【讨论】:

  • 这个答案类似于 VladoS 建议的答案。
  • 确实如此。不幸的是,我错过了。但是,我的答案不是更清楚吗?
【解决方案5】:

不完全是结尾,但比子字符串解决方案看起来更好,并且仍然适用于某些情况:

<xsl:template match="*[contains(name(), 'substr')]"/>

【讨论】:

  • 这与外观无关。 contains() 将产生误报,例如,子字符串为“_01”且字符串为“3_01_02”。
  • 当然,但我发现我的情况更容易编写和阅读,我知道 'substr' 只会出现在最后。
【解决方案6】:

在特殊情况下,如果你知道某个字符不能包含在标签中 例如 § 你可以这样做:

<xsl:if test="contains(concat(code_no,'§'),'01§')">
  <td align="left" width="33%"><SPAN style="font-size: 12pt; font-family: Arial;">
    <a> <b><u><xsl:value-of select="//city"/>, <xsl:value-of select="//state"/> 
    </u></b></a></SPAN></td>
</xsl:if>

【讨论】: