ID以变量结尾的选择列表

时间:2011-10-28 00:22:38

标签: xslt

我想为给定的id选择所有节点,但这可能会以一个额外的数字结尾。我怎么能这样做?

示例:

 <group id="list">
 <group id="list1">
 <group id="list2">
 <group id="map">
 <group id="map1">

我现在拥有的声明:

<xsl:variable name="rule">
<data>
    <node>list</node>
    <node>map</node>
</data>
</xsl:variable>

<xsl:template match="/">
    <xsl:apply-templates select=".//group[ @id = exslt:node-set($rule)/data/node]"/>
</xsl:template>

它只允许我处理“规则”列表中指定的节点。 [XSLT v1.0]

请告知。

1 个答案:

答案 0 :(得分:1)

<强>予。 XSLT 1.0解决方案:

这种转变:

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

 <xsl:param name="pIds">
  <id>list</id>
  <id>map</id>
 </xsl:param>

 <xsl:variable name="vIds" select=
  "document('')/*/xsl:param[@name='pIds']/*"/>

 <xsl:template match="group">
  <xsl:if test=
  "$vIds[. = current()/@id
        or
         starts-with(current()/@id, .)
        and
         substring-after(current()/@id, .)
        =
         floor(substring-after(current()/@id, .))
        ]
  ">
   <!-- Processing here: -->
   <xsl:copy-of select="."/>
  </xsl:if>
 </xsl:template>
</xsl:stylesheet>

应用于此XML文档时

<t>
 <group id="list"/>
 <group id="list1"/>
 <group id="listX"/>
 <group id="list2"/>
 <group id="map"/>
 <group id="map123Z"/>
 <group id="map1"/>
</t>

进程(在此示例中完全复制)完全匹配的节点

<group id="list"/>
<group id="list1"/>
<group id="list2"/>
<group id="map"/>
<group id="map1"/>

<强>解释

  1. 使用标准XPath函数 starts-with() substring-after() floor()

  2. 如果字符串可以转换为整数,则可以轻松测试:floor($s) = $s

  3. <强> II。 XSLT 2.0解决方案:

    <xsl:stylesheet version="2.0"
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
     xmlns:xs="http://www.w3.org/2001/XMLSchema">
     <xsl:output omit-xml-declaration="yes" indent="yes"/>
    
     <xsl:param name="pIds" select="'list', 'map'"/>
    
     <xsl:variable name="vIds" select=
      "document('')/*/xsl:param[@name='pIds']/*"/>
    
     <xsl:template match=
     "group
       [@id = $pIds
       or
        $pIds
          [starts-with(current()/@id, .)
         and
            substring-after(current()/@id, .)
           castable as
            xs:integer
           ]
        ]
     ">
       <!-- Processing here: -->
       <xsl:copy-of select="."/>
     </xsl:template>
    </xsl:stylesheet>
    

    解释:此解决方案与XSLT 1.0解决方案非常相似,但存在以下主要差异:

    1. 在XSLT 2.0中,允许在匹配模式中具有变量/参数引用。使用此方法,我们避免模板体内的<xsl:if>

    2. 我们定义参数以包含所需字符串的序列。

    3. 我们使用标准的XPath 2.0运算符 castable as