检查字符串是否出现在XSLT中的节点值中

时间:2011-09-27 16:04:06

标签: xslt

我有以下XML:

<nodes>
  <node>
    <articles>125,1,9027</articles>
  </node>
  <node>
    <articles>999,48,123</articles>
  </node>
  <node>
    <articles>123,1234,4345,567</articles>
  </node>
</nodes>

我需要编写一些XSLT,它只返回具有paricular article id的节点,所以在上面的例子中,只有那些包含第123条的节点。

我的XSLT并不好,所以我正在努力解决这个问题。我想做这样的事情,但我知道XSLT中没有'instring'扩展方法:

<xsl:variable name="currentNodeId" select="1234"/>

<xsl:for-each select="$allNodes [instring(articles,$currentNodeId)]">
  <!-- Output stuff -->
</xsl:for-each>

我知道这很黑,但不确定解决这个问题的最佳方法。节点集可能很大,节点内的文章ID数量也可能很大,所以我非常确定将节点的值拆分为一个节点集是不是'这将非常有效,但我可能是错的!

非常感谢任何有关最佳方法的帮助,谢谢。

2 个答案:

答案 0 :(得分:1)

XSLT 2.0:这将匹配文本中完全 123的文章。

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:variable name="id" select="123"/>

<xsl:template match="/">
    <xsl:for-each select="//node[matches(articles, concat('(^|\D)', $id, '($|\D)'))]">
      <xsl:value-of select="current()"/>
    </xsl:for-each>
  </xsl:template>
</xsl:stylesheet>

示例输入:

<?xml version="1.0" encoding="utf-8"?>
<nodes>
  <node>
    <articles>1234,1000,9027</articles>
  </node>
  <node>
    <articles>999,48,01234</articles>
  </node>
  <node>
    <articles>123,1234,4345,567</articles>
  </node>
  <node>
    <articles> 123 , 456 </articles>
  </node>
</nodes>

输出:

123,1234,4345,567

 123 , 456 

我不知道如何有效地使用XSLT 1.0,但OP表示他正在使用XSLT 2.0,所以这应该是一个充分的答案。

答案 1 :(得分:0)

在XSLT 1.0中,您可以使用此简单解决方案,它使用normalize-spacetranslatecontainssubstringstring-length函数。

示例输入XML:

<nodes>
  <node>
    <articles>125,1,9027</articles>
  </node>
  <node>
    <articles>999,48,123</articles>
  </node>
  <node>
    <articles>123,1234,4345,567</articles>
  </node>
  <node>
    <articles> 123 , 456 </articles>
  </node>
  <node>
    <articles>789, 456</articles>
  </node>
  <node>
    <articles> 123 </articles>
  </node>
  <node>
    <articles>456, 123 ,789</articles>
  </node>
</nodes>

XSLT:

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

  <xsl:variable name="id" select="123"/>

  <xsl:template match="node">
    <xsl:variable name="s" select="translate(normalize-space(articles/.), ' ', '')"/>

    <xsl:if test="$s = $id 
            or contains($s, concat($id, ','))
            or substring($s, string-length($s) - string-length($id) + 1, string-length($id)) = $id">
      <xsl:copy-of select="."/>
    </xsl:if>


  </xsl:template>

  <xsl:template match="/nodes">
    <xsl:copy>
      <xsl:apply-templates select="node"/>
    </xsl:copy>
  </xsl:template>

</xsl:stylesheet>

输出:

<nodes>
  <node>
    <articles>999,48,123</articles>
  </node>
  <node>
    <articles>123,1234,4345,567</articles>
  </node>
  <node>
    <articles> 123 , 456 </articles>
  </node>
  <node>
    <articles> 123 </articles>
  </node>
  <node>
    <articles>456, 123 ,789</articles>
  </node>
</nodes>