Question

I have the following code (xml and xslt) and I would like to count some xml elements with 2 conditions.

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 code:

<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>

The first two counts are working correctly (there is just one condition on these counts) but the third count does not work because there are two conditions. Any suggestion how to make it work? Thanks.

Était-ce utile?

La solution

Use this expression, if you want to count places which are "house" and have "kitchen":

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

Autres conseils

Each predicate restricts the result node-set of the previous context. If you have two predicates on a location path, you have to consider that the first one restricts the result node-set of the location path expression creating a new context (with less nodes), and then you are applying the second predicate on this smaller set.

In your case, this expression:

/home/place/property

results in a node-set with 18 items. When you add the first predicate:

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

you now have a new context, with only four nodes:

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

Your second predicate is applied on only these four nodes. When you add it

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

to your expression (or to any one of those nodes above), it will return an empty set.

If you add any of those predicates to your location path individually you do get results. If you want to consider all of them you should perform a union operation of your sets:

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

which will give you seven nodes.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top