0

这是我的 XML 和 XSLT 代码

<root>
    <act>
        <acts id>123</acts>
    </act>
    <comp>
        <comps id>233</comps>
    </comp>
</root>


<xsl:for-each select="act/acts">
    <xsl:variable name="contactid" select="@id"/>
    <xsl:for-each select="root/comp/comps">
        <xsl:variable name="var" select="boolean(contactid=@id)"/>
    </xsl:for-each>
    <xsl:choose>
        <xsl:when test="$var='true'">
          . . . do this . . .
        </xsl:when>
        <xsl:otherwise>
          . . . do that . . .
        </xsl:otherwise>
    </xsl:choose>
</xsl:for-each>

我想动态分配真或假var并在内部使用它<xsl:choose>进行布尔测试。for-each我希望这有助于找到更好的解决方案来摆脱

4

2 回答 2

3

首先要注意的是 XSLT 中的变量是不可变的,一旦初始化就不能更改。XSLT 的主要问题是您在xsl:for-each块中定义变量,因此它只存在于该块的范围内。它不是全局变量。每次都会定义一个只能在xsl:for-each中使用的新变量

从您的 XSLT 来看,您似乎想要遍历 act元素并根据是否存在具有相同值的comps元素执行特定操作。另一种方法是定义一个键来查找comps元素,就像这样

<xsl:key name="comps" match="comps" use="@id" />

然后你可以简单地检查一个comps元素是否存在(假设你定位在一个act元素上。

<xsl:choose>
   <xsl:when test="key('comps', @id)">Yes</xsl:when>
   <xsl:otherwise>No</xsl:otherwise>
</xsl:choose>

这是完整的 XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:key name="comps" match="comps" use="@id" />

   <xsl:template match="/root">
      <xsl:apply-templates select="act/acts" />
   </xsl:template>

   <xsl:template match="acts">
      <xsl:choose>
         <xsl:when test="key('comps', @id)"><res>Yes</res></xsl:when>
         <xsl:otherwise><res>No</res></xsl:otherwise>
      </xsl:choose>
   </xsl:template>
</xsl:stylesheet>

应用于以下(格式良好的)XML 时

<root>
   <act>
      <acts id="123"/>
   </act>
   <comp>
      <comps id="233"/>
   </comp>
</root>

以下是输出

但是,通常最好在 XSLT 中避免使用诸如xsl:choosexsl:if之类的条件语句。相反,您可以构建 XSLT 以利用模板匹配。这是替代方法

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:key name="comps" match="comps" use="@id" />

   <xsl:template match="/root">
      <xsl:apply-templates select="act/acts" />
   </xsl:template>

   <xsl:template match="acts[key('comps', @id)]">
      <res>Yes</res>
   </xsl:template>

   <xsl:template match="acts">
      <res>No</res>
   </xsl:template>
</xsl:stylesheet>

当应用于相同的 XML 时,输出相同的结果。请注意,在匹配存在组合的情况时,行为节点的更具体的模板将优先考虑。

于 2012-04-19T07:25:27.623 回答
1

您的 xml 文件中有一些错误,但假设您的意思是:

<root>
    <act><acts id="123"></acts></act>
    <comp><comps id="233"></comps></comp>
</root>

这是一个完整的解决方案:

<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 

    <xsl:template match="/">
        <doc>   
           <xsl:apply-templates select="root/comp/comps"/>  
        </doc>
    </xsl:template>

    <xsl:template match="root/comp/comps"> 
        <xsl:variable name="compsid" select="@id"></xsl:variable>
        <xsl:choose>
            <xsl:when test="count(/root/act/acts[@id=$compsid])&gt;0">Do This</xsl:when>
            <xsl:otherwise>Do That</xsl:otherwise>
        </xsl:choose>
    </xsl:template> 

</xsl:stylesheet>
于 2012-04-18T18:58:48.083 回答