检查字符串XSL是否存在于字符串数组中

时间:2015-01-20 20:39:08

标签: arrays xml xslt

是否可以检查XSL中字符串数组中是否存在字符串? 我有以下XML:

<?xml version="1.0" encoding="UTF-8"?>
<ItemsArr>
  <it attr="DANCHO">
    <title>1</title>
  </it>
  <it attr="DAN">
    <title>2</title>
  </it>
  <it attr="IVANCHO">
    <title>3</title>
  </it>
  <it attr="DRAGANCHO">
    <title>4</title>
  </it>
  <it attr="PETKANCHO">
    <title>5</title>
  </it>
  <keys>
    <itemKey>DANCHO</itemKey>
    <itemKey>THISISONLYFORTESTING</itemKey>
  </keys>
</ItemsArr>

以下的XSL转换:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
  <html>
  <body>
    <table border="1">
    <xsl:variable name="items" select="ItemsArr/keys/itemKey"/>

    <xsl:for-each select="/ItemsArr/it[contains($items,@attr)]">
     <tr>
        <td><xsl:value-of select="@attr"/></td>
        <td><xsl:value-of select="title"/></td>
      </tr>
    </xsl:for-each>
    </table>

  </body>
  </html>
</xsl:template>
</xsl:stylesheet>

我想将所有键(ItemsArr / Keys)存储在一个数组($ items)中,然后遍历it-s,$ items数组中存在attr值。 请注意,使用上述数据,它们都被选中。 如果交换了两个键(DANCHO和THISISONLYFORTESTING),则不会选择任何内容。

3 个答案:

答案 0 :(得分:1)

contains实际上是一个字符串函数,它检查第一个字符串是否“包含”第二个字符串。它不适用于节点集(在XSLT 1.0中,如果你传递一个节点集,它将获得该集合中第一个节点的文本值。在XSLT 2.0中,它会出错)。 / p>

您可以使用的表达式就是这个......

<xsl:for-each select="/ItemsArr/it[@attr = $items/text()]">

因此,如果attr属性与节点集中任何项目的文本节点匹配,则为真。

或者,考虑使用密钥更有效地查找值。

<xsl:key name="items" match="itemKey" use="text()" />

然后你会像这样查找

<xsl:for-each select="/ItemsArr/it[key('items', @attr)]">

试试这个XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:key name="items" match="itemKey" use="text()" />

<xsl:template match="/">
  <html>
  <body>
    <table border="1">
    <xsl:variable name="items" select="ItemsArr/keys/itemKey"/>

    <xsl:for-each select="/ItemsArr/it[key('items', @attr)]">
     <tr>
        <td><xsl:value-of select="@attr"/></td>
        <td><xsl:value-of select="title"/></td>
      </tr>
    </xsl:for-each>
    </table>

  </body>
  </html>
</xsl:template>
</xsl:stylesheet>

答案 1 :(得分:0)

您应该说明您的问题而不是您认为要解决的问题,因为XSLT 1或2中没有数组数据结构。

如果您的问题是要实现数据结构,您可以查找xsl:key的用途。所以你应该阅读xsl:key和关键功能。

然后在您的代码密钥(&#34; array&#34;,pathToLookupValue)中将告诉您所提供的路径中的值是否存在于您设置的密钥中。

答案 2 :(得分:0)

我知道以下内容并不是对问题的直接答案,因为我怀疑这样做的目的是应用本机XSLT构造。但是,可以说我通过引入基于Saxon XSLT处理器支持的Java代码的扩展功能(enter image description here)解决了类似的问题。您也可以使用Saxon或内置的.NET XSLT处理器,使用Python XSLT处理器或您选择的任何支持扩展功能的XSLT处理器,在.NET中执行相同的操作。

我编写的函数需要三个参数:1)分隔符(例如逗号); 2)由分隔符分隔的字符串; 3)代表查询内容的字符串。如果我们假设该函数名为“ contains”,则应用该函数的示例为:“ contains(“ 1,2,3,6”,“,”,“ 3”)”。 另外,XSLT 2.0和更高版本支持定义这样的功能,因此这是另一种方法。