根据属性获取上层XML节点值

时间:2016-06-14 08:51:33

标签: xml xslt attributes

我只是尝试编写XSL 1.0代码(使用XSLT转换XML),这允许我根据低级属性给出属性值。 为了清楚说明,一个例子可能很有用:

<age_list>
  <age i="13">
    <type j="min"/>
  </age>
  <age i="22">
    <type j="max"/>
  <age_list>
</age_list>

所以,我想提取年龄属性i,但我需要知道它是否是最小或最大年龄,例如,某些电影是针对18岁以下的孩子禁止的,但推荐的年龄虽然是12岁。 因此,每部电影都有一个年龄列表,但不是每个年龄列表都包含最小和最大年龄,有时只有最大,有时只有最小,有时甚至两者。 如果没有给出min,它会自动设置为0,而max的值设置为999(如果没有给出)。 那么,我怎么能实现这个目标呢?

我遍历所有年龄列表并进行以下测试:

<xsl:choose>
    <xsl:when test="./age/type[@j='MIN']">
        <xsl:value-of select="./age/@j" />
    </xsl:when>
    <xsl:otherwise>
        <xsl:text>0</xsl:text>
    </xsl:otherwise>
</xsl:choose>
<xsl:choose>
    <xsl:when test="./age/type[@j='MAX']">
        <xsl:value-of select="./age/@j" />
    </xsl:when>
    <xsl:otherwise>
        <xsl:text>999</xsl:text>
    </xsl:otherwise>
</xsl:choose>

但它让我获得max和min相同的值,这听起来很合理,因为我指的是当前年龄而不依赖于类型的属性j。

1 个答案:

答案 0 :(得分:0)

XML和XSLT区分大小写。在XML中,您的j属性的值为min,但在您的XSLT中,您正在寻找不同的MIN

此外,您的代码首先测试给定类型的age属性,但xsl:when不会更改您当前的上下文,这意味着当您执行<xsl:value-of select="./age/@j" />时,您刚刚获得第一个age元素,而不是具有所需类型的元素。

请改为尝试:

<xsl:choose>
    <xsl:when test="age[type/@j='min']">
        <xsl:value-of select="age[type/@j='min']/@i" />
    </xsl:when>
    <xsl:otherwise>
        <xsl:text>0</xsl:text>
    </xsl:otherwise>
</xsl:choose>
<xsl:choose>
    <xsl:when test="age[type/@j='max']">
        <xsl:value-of select="age[type/@j='max']/@i" />
    </xsl:when>
    <xsl:otherwise>
        <xsl:text>999</xsl:text>
    </xsl:otherwise>
</xsl:choose>

您可以避免使用变量重复表达

<xsl:variable name="min" select="age[type/@j='min']" />
<xsl:choose>
    <xsl:when test="$min">
        <xsl:value-of select="$min/@i" />
    </xsl:when>
    <xsl:otherwise>
        <xsl:text>0</xsl:text>
    </xsl:otherwise>
</xsl:choose>

<xsl:variable name="max" select="age[type/@j='max']" />
<xsl:choose>
    <xsl:when test="$max">
        <xsl:value-of select="$max/@i" />
    </xsl:when>
    <xsl:otherwise>
        <xsl:text>999</xsl:text>
    </xsl:otherwise>
</xsl:choose>