如何使XSLT仅在存在元素时显示它?

时间:2018-10-17 06:46:54

标签: xml xslt

这是我的XML的一部分:

<ing>
    <amt>
        <qty>12</qty>
    </amt>
    <item>chicken thighs (boneless and skinned)</item>
</ing>
<ing>
    <amt>
        <qty>3</qty>
    </amt>
    <item>bay leaves</item>
</ing>
<ing>
    <amt>
        <qty>300</qty>
        <unit system="metric">gram(s)</unit>
    </amt>
    <item>oyster mushroom(s)</item>
    <prep>(torn into strips)</prep>
</ing>

不是每个<ing>元素都有一个<prep>元素,但是我不希望prep元素行位于代码中(如果它不在XML中)。

这是我当前的XSLT:

<xsl:template match="recipeml/recipe/ingredients">
    <h2><xsl:text>Ingredients</xsl:text></h2> 
    <xsl:for-each select="ing">
        <li>
            <xsl:value-of select="item"/>
            <ul><xsl:value-of select="amt"/></ul>
            <xsl:choose>
                <xsl:when test="following-sibling::prep">
                    <ul><i><xsl:value-of select="prep"/></i></ul>
                </xsl:when>
            </xsl:choose>
        </li>
    </xsl:for-each> 
</xsl:template>

到目前为止,我尝试过的任何一项都能使我:

<li>oyster mushroom(s)
  <ul>
      300
      gram(s)
  </ul>
</li>

没有<prep>或每个<ing>都有一个,其中许多为空(<prep></prep>

有没有一种方法可以使它仅在有元素的情况下显示?

2 个答案:

答案 0 :(得分:0)

您已经在for-each循环中的ing节点的上下文中,更改

<xsl:when test="following-sibling::prep">

<xsl:when test="prep">

测试任何子prep节点

答案 1 :(得分:0)

  

有没有一种方法可以使它仅在有元素的情况下显示?

是的。使用模板匹配。在这里,<xsl:template match="prep">仅在存在<prep>元素时(即select="prep"选择任何内容时)才被实际调用。

<xsl:template match="ingredients">
    <h2><xsl:text>Ingredients</xsl:text></h2>
    <ul>
        <xsl:apply-templates select="ing" />
    </ul>
</xsl:template>

<xsl:template match="ing">
    <li>
        <div class="item"><xsl:value-of select="item" /></div>
        <div class="amount"><xsl:value-of select="amt"/></div>
        <xsl:apply-templates select="prep" />
    </li>
</xsl:template>

<xsl:template match="prep">
    <div class="preparation"><xsl:value-of select="." /></div>
</xsl:template>

我也更正了HTML。您嵌套的大多数元素都不能以这种方式合法地嵌套。无论如何,使用CSS都容易得多,因此我使用了<div>和CSS类。