My XML Code (containing pubs and people):
<document>
<pubs>
<pub id="pub1">
<open>true</open>
</pub>
<pub id="pub2">
<open>false</open>
</pub>
</pubs>
<people>
<person>
<name>John</name>
<pubId>pub1</pubId>
</person>
<person>
<name>Paul</name>
<pubId>pub2</pubId>
</person>
</people>
</document>
uses a reference from <person> to <pub> (person/pubId references pub[@id]). Pubs themselves have a boolean <open> (stating whether the pub is opened or closed).
Using XSLT, I want to be able to count() the number of people that can go to the pub. In order to go to a pub, the pub must have an <open> value of true.
Two possible solutions that I can’t quite code up:
-
Iterate through the people and keep track of the number:
<xsl:for-each select="person"> <xsl:variable name="pId" select="pubId" /> <xsl:if test="root()/document/pubs/pub[@pubId=$pId]/open = 'true'" > <!-- any way to keep track of this number? --> </xsl:if> </xsl:for-each> -
Use the count() function directly:
<count> <xsl:value-of select="count(//person[root()/document/pubs/pub[@id = pubId]/open = 'true'])" /> </count>
The second option seems more concise and correct, but I can’t get it to work.
Any ideas?
Use this XPath 1.0 one-liner:
This returns the count of
personelements in this document that have at least onepubIdchild such that there is apubelement whoseidattribute’s string value equals thatpubIdand whoseopenchild’s string value is the string"true".Here is an XSLT-based verification:
When this transformation is applied on the provided XML document:
the Xpath expression is evaluated and the result of this evaluation is copied to the output: