xslt测试标签的参数

时间:2011-05-27 08:14:58

标签: xml xslt xsl-fo

我想在xslt中创建一个模板,其中包含我匹配的标签参数的条件。

例如: 如果我有标记<par class="class1"><par class="class2">

我想创建一个这样的模板:

<xsl:template match="par">
 <xsl:if test="class=class1">
  <fo:block
    space-before="3pt"
    space-after="3pt">

    <xsl:apply-templates />

  </fo:block>
 </xsl:if>
 <xsl:otherwise>
  <fo:block
    space-before="10pt"
    space-after="10pt">

    <xsl:apply-templates />

  </fo:block>
 </xsl:otherwise>
</xsl:template>

但它不起作用。如何测试标签的参数?

提前感谢。

4 个答案:

答案 0 :(得分:4)

首先<xsl:if/>是“独立”指令。如果您需要默认情况,则可以使用xsl:choose

在您的代码中xsl:if测试xpath无效。使用@attribute_name进行属性访问,使用单引号进行字符串文字。

固定代码:

<xsl:template match="par">
 <xsl:choose>
 <xsl:when test="@class = 'class1'">
  <fo:block
    space-before="3pt"
    space-after="3pt">
    <xsl:apply-templates />
  </fo:block>
 </xsl:when>
 <xsl:otherwise>
  <fo:block
    space-before="10pt"
    space-after="10pt">
    <xsl:apply-templates />
  </fo:block>
 </xsl:otherwise>
 <xsl:choose>
</xsl:template>

但是你的任务有更优雅的解决方案:

<xsl:template match="par">
    <fo:block
      space-before="10pt"
      space-after="10pt">

        <xsl:if test="@class = 'class1'">
            <xsl:attribute name="space-before" select="'3pt'"/>
            <xsl:attribute name="space-after" select="'3pt'"/>
        </xsl:if>

        <xsl:apply-templates />

    </fo:block>
</xsl:template>

答案 1 :(得分:3)

您实际上可以使用其他模板,而不是使用<xsl:if>。像这样:

<xsl:template match="par[@class='class1']">
  ..
</xsl:template>

<xsl:template match="par">
  ..
</xsl:template>

第二个模板用于与第一个不匹配的任何par元素。虽然第二个模板可以匹配所有par元素,但第一个模板会被第一个模板覆盖,因为后者更具体。

答案 2 :(得分:2)

这些“参数”的技术术语是“属性”(以防万一有助于将来的搜索),您可以使用@class等来引用它们。

另请注意,<xsl:otherwise>不适用于<xsl:if>,而适用于<xsl:choose>

<xsl:template match="par">
  <xsl:choose>
    <xsl:when test="@class='class1'">
      <fo:block
        space-before="3pt"
        space-after="3pt">

        <xsl:apply-templates />

      </fo:block>
    </xsl:when>
    <xsl:otherwise>
      <fo:block
        space-before="10pt"
        space-after="10pt">

        <xsl:apply-templates />

      </fo:block>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

或者,为了更好地显示实际差异,

<xsl:template match="par">
  <fo:block>
    <xsl:choose>
      <xsl:when test="@class='class1'">
        <xsl:attribute name='space-before'>3pt</xsl:attribute>
        <xsl:attribute name='space-after'>3pt</xsl:attribute>
      </xsl:when>
      <xsl:otherwise>
        <xsl:attribute name='space-before'>10pt</xsl:attribute>
        <xsl:attribute name='space-after'>10pt</xsl:attribute>
      </xsl:otherwise>
    </xsl:choose>
    <xsl:apply-templates/>
  </fo:block>
</xsl:template>

答案 3 :(得分:1)

使用@访问属性,您可以按如下方式测试属性的值:

<xsl:if test="@class = 'class1'">
    ....
</xsl:if>

或使用

检查属性是否存在
<xsl:if test="@class">
   ...
</xsl:if>