计算具有多个条件和精确属性的xml元素

时间:2014-05-15 11:55:40

标签: xml xslt count multiple-conditions

我有以下代码(xml和xslt),我想用两个条件计算一些xml元素。

XMLcode:

<home>
    <place Value='place1'>
        <property Name="Type" Value="house" />
        <property Name="Context" Value="roof" />
        <property Name="Color" Value="blue" />
    </place>
    <place Value='place2'>
        <property Name="Type" Value="house" />
        <property Name="Context" Value="kitchen" />
        <property Name="Color" Value="red" />
    </place>
    <place Value='>
        <property Name="Type" Value="house" />
        <property Name="Context" Value="floor" />
        <property Name="Color" Value="black" />
    </place>
    <place Value='place4'>
        <property Name="Type" Value="house" />
        <property Name="Context" Value="kitchen" />
        <property Name="Color" Value="black" />
    </place>
    <place Value='place5'>
        <property Name="Type" Value="apartment" />
        <property Name="Context" Value="roof" />
        <property Name="Color" Value="blue" />
    </place>
    <place Value='place6'>
        <property Name="Type" Value="apartment" />
        <property Name="Context" Value="kitchen" />
        <property Name="Color" Value="red" />
    </place>
</home>

xslt代码:

<html>
<body>
<table border="1" cellspacing="0" cellpadding="3">
    <tr>
    <td>Place</td>
    <td>Type</td>
    <td>Context</td>
    <td>Color</td>
    </tr>
    <xsl:for-each select="place">
        <tr>
            <td><xsl:value-of select="@Value" /></td>
            <td><xsl:value-of select="property[@Name='Type']/@Value" /></td>
            <td><xsl:value-of select="property[@Name='Context']/@Value" /></td>
            <td><xsl:value-of select="property[@Name='Color']/@Value" /></td>
        </tr>
    </xsl:for-each>
</table>

<table>
    <tr>
        <td>
            Number of house:
        </td>
        <td>
            <xsl:value-of select="count(place/property[@Name='Type' and @Value='house'])"/>
        </td>
    </tr>
    <tr>
        <td>
            Number of kitchen:
        </td>
        <td>
            <xsl:value-of select="count(place/property[@Name='Context' and @Value='kitchen'])"/>
        </td>
    </tr>
    <tr>
        <td>
             Number of house with kitchen:
        </td>
        <td>
            <xsl:value-of select="count(place/property[@Name='Type' and @Value='house'][@Name='Context' and @Value='kitchen'])"/>
        </td>
    </tr>
</table>

</body>
</html>

前两个计数正常工作(这些计数只有一个条件)但第三个计数不起作用,因为有两个条件。有什么建议如何使其工作? 感谢。

2 个答案:

答案 0 :(得分:1)

如果您想要计算“住宅”并拥有“厨房”的地方,请使用此表达式:

count(home/place[property[@Name='Type' and @Value='house'] and property[@Name='Context' and @Value='kitchen']])

答案 1 :(得分:0)

每个谓词都限制前一个上下文的结果节点集。如果在位置路径上有两个谓词,则必须考虑第一个限制位置路径表达式的结果节点集创建新上下文(具有较少的节点),然后在这个较小的上应用第二个谓词集。

在您的情况下,这个表达式:

/home/place/property

会产生包含18个项目的节点集。添加第一个谓词时:

/home/place/property[@Name='Type' and @Value='house']

您现在有了一个新的上下文,只有四个节点:

/home[1]/place[1]/property[1]
/home[1]/place[2]/property[1]
/home[1]/place[3]/property[1]
/home[1]/place[4]/property[1]

您的第二个谓词仅适用于这四个节点。当你添加它

[@Name='Context' and @Value='kitchen'] 

到你的表达式(或上面任何一个节点),它将返回一个空集。

如果您将这些谓词中的任何一个单独添加到您的位置路径,那么 会获得结果。如果你想考虑所有这些,你应该对你的集合执行 union 操作:

/home/place/property[@Name='Type' and @Value='house'] | /home/place/property[@Name='Context' and @Value='kitchen']

将为您提供七个节点。