使用“应用”模板时,如何在xslt中的选择条件中使用两个条件

时间:2011-10-24 06:06:54

标签: xslt xpath

<xsl:apply-templates mode="block2sequence" select="NewDataSet/Table[CTD_CTD_PKG_ID =$PackageId][position()=1] and NewDataSet/Table[CTD_SEQ_NUM =$strXSLMsgType][position()=1]"/>

为什么我不能在上面的选择条件中使用两个条件,任何人都可以建议我

2 个答案:

答案 0 :(得分:4)

<xsl:apply-templates mode="block2" 
     select="NewDataSet/Table[CTD_CTD_PKG_ID =$PackageId][position()=1] "/>
     

为什么我不能在上面的选择条件中使用两个条件

我想这是指,“为什么不能在同一个谓词中指定这两个条件?

答案是表达式

NewDataSet/Table[CTD_CTD_PKG_ID =$PackageId and position() = 1]

与上面的第一个表达式完全不相同。

第一个表达式选择Table的第一个NewDataSet子项,使其CTD_CTD_PKG_ID子项的字符串值等于$PackageId的字符串值。在这种情况下,我们不知道将选择NewDataSet的哪个孩子(在哪个位置) - 将选择恰好是具有指定属性的第一个孩子。

另一方面,后者表达式只选择Table 的第一个NewDataSet子项,只有CTD_CTD_PKG_ID子项的字符串值等于字符串值$PackageId。在这种情况下,如果选择了任何内容,则它将是第一个Table子项。

如果你想要一个等价表达式到第一个,只有一个谓词,一个这样的表达式是:

NewDataSet/Table
      [CTD_CTD_PKG_ID =$PackageId 
     and 
       not(preceding-sibling::Table[CTD_CTD_PKG_ID =$PackageId ])
      ]

更新:OP发布了一个代码段:

 <xsl:apply-templates mode="block2sequence" select=
    "NewDataSet/Table[CTD_CTD_PKG_ID =$PackageId][position()=1]
    and
     NewDataSet/Table[CTD_SEQ_NUM =$strXSLMsgType][position()=1]"/>

此代码将导致XSLT处理器在编译时抛出错误

select属性的值是布尔值(expr1和expr2),但XSLT 1.0和XSLT 2.0中的模板只能应用于节点。布尔值不是节点 - 因此是错误。

解决方案

我的第一个猜测是您希望模板应用于两个节点。如果是这样,那么使用:

 <xsl:apply-templates mode="block2sequence" select=
    "NewDataSet/Table[CTD_CTD_PKG_ID =$PackageId][1]
    |
     NewDataSet/Table[CTD_SEQ_NUM =$strXSLMsgType][1]"/>

我的第二个猜测是您希望模板仅应用于两个节点中的第一个节点。如果是这样,那么使用:

 <xsl:apply-templates mode="block2sequence" select=
    "(NewDataSet/Table[CTD_CTD_PKG_ID =$PackageId]
    |
     NewDataSet/Table[CTD_SEQ_NUM =$strXSLMsgType]
     )
      [1]
"/>

备注

  1. 请了解如何提问 - 提供所有相关数据并解释 - 在问题中,而不是在随后的评论中。

  2. 您是否知道[1]相当于[position()=1]而且更短?

答案 1 :(得分:1)

您可以使用两个条件,表达式看起来非常正确。如果失败并出现错误,请告诉我们错误。如果没有选择你想要的,那么(a)向我们展示你的源文件,(b)告诉我们你想要选择什么。

(你知道,你的问题提供的信息很少,你不会给人的印象是你真的想要答案。)