XSLT: Evaluate two XML parent nodes and return a count of how many matches

I've got a XML file that contains two AAA elements:

<Root>
    <AAA>
        <BBB number="1">
            <CCC value="1" myAttribute="N" />
            <CCC value="2" myAttribute="Y" />
            <CCC value="3" myAttribute="N" />
        </BBB>
        <BBB number="2">
            <CCC value="1" myAttribute="N" />
            <CCC value="2" myAttribute="N" />
            <CCC value="3" myAttribute="Y" />
        </BBB>
    </AAA>
    <AAA>
        <BBB number="1">
            <CCC value="1" myAttribute="N" />
            <CCC value="2" myAttribute="Y" />
            <CCC value="3" myAttribute="N" />
        </BBB>
        <BBB number="2">
            <CCC value="1" myAttribute="Y" />
            <CCC value="2" myAttribute="N" />
            <CCC value="3" myAttribute="N" />
        </BBB>
    </AAA>
</Root>

Basically, the process should return "1" because <BBB number="1"> in AAA[1] and AAA[2] has the same CCC element with a myAttribute="Y".  Each BBB node will only have one CCC node that has myAttribute="Y".

Could someone provide me with the best way to do this in XSLT.  Keep in mind that the files I'm processing are fairly small (Perhaps up to 15 BBB nodes each with up to 10 CCC nodes) and thus the XSLT method used should be suited to small rather than large files (if relevant).

Also, I'll be using Oracle 9.2's XSLT processor so please keep the solution non-processor specific.  I don't need the PL/SQL code, just the XLS stylesheet.

Thanks very much!
LVL 2
gadkinsAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Gertone (Geert Bormans)Information ArchitectCommented:
Will there always only be two AAA nodes?
gadkinsAuthor Commented:
Yes.
gadkinsAuthor Commented:
Just want to clarify that I want a count of how many BBB have the matching CCC node set to Y.

I've been having a crack here myself and have got something that returns either 0 or 1 for each matching CCC that has a myAttribute of "Y" in both AAA nodes, but I don't have a clue how to add em up.  So right now my output it 10000001000  (I'm testing with more data than I specified here).  It's so frustrating!  XSLT just makes me want to take up a less stressful job... like defusing bombs.  :)
Exploring ASP.NET Core: Fundamentals

Learn to build web apps and services, IoT apps, and mobile backends by covering the fundamentals of ASP.NET Core and  exploring the core foundations for app libraries.

GreybirdCommented:
To clarify things :
Do you want to count CCC nodes that have the @myAttribute to 'Y' have a defined @value under different BBB that have the same @number as only one or as as many as there is of BBB ?
Gertone (Geert Bormans)Information ArchitectCommented:
I hacked together something that does the job,
not that I am proud of it, it is pretty straightforward,
but it works

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:key name="ckey" match="//AAA[1]/BBB/CCC[@myAttribute = 'Y']" use="../@number"/>
 
    <xsl:template match="/">
        <xsl:param name="bindex">1</xsl:param>
        <xsl:param name="Ccount">0</xsl:param>
        <xsl:apply-templates select="key('ckey', $bindex)">
            <xsl:with-param name="bindex" select="$bindex"/>
            <xsl:with-param name="Ccount" select="$Ccount"/>
        </xsl:apply-templates>
    </xsl:template>
 
    <xsl:template match="CCC">
        <xsl:param name="bindex"/>
        <xsl:param name="Ccount"/>
        <xsl:param name="VALUE"><xsl:value-of select="@value"/></xsl:param>
        <xsl:choose>
            <xsl:when test="//AAA[2]/BBB[@number = $bindex]/CCC[@value = $VALUE]/@myAttribute = 'Y'">
                <xsl:call-template name="CCount">
            <xsl:with-param name="bindex" select="$bindex + 1"/>
            <xsl:with-param name="Ccount" select="$Ccount + 1"/>
                </xsl:call-template>
            </xsl:when>
            <xsl:otherwise>
                <xsl:call-template name="CCount">
            <xsl:with-param name="bindex" select="$bindex + 1"/>
            <xsl:with-param name="Ccount" select="$Ccount"/>
                </xsl:call-template>
            </xsl:otherwise>
         </xsl:choose>
 </xsl:template>
 
    <xsl:template name="CCount">
        <xsl:param name="bindex"/>
        <xsl:param name="Ccount"/>
        <xsl:choose>
            <xsl:when test="key('ckey', $bindex)">
                <xsl:apply-templates select="key('ckey', $bindex)">
                    <xsl:with-param name="bindex" select="$bindex"/>
                    <xsl:with-param name="Ccount" select="$Ccount "/>
                </xsl:apply-templates>
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="$Ccount"/><xsl:text> nodes found</xsl:text>
            </xsl:otherwise>
        </xsl:choose>
       
    </xsl:template>
</xsl:stylesheet>

I thought I could manage it with one single XPath,
but that was above my instant capabilities
cheers

Gertone

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Gertone (Geert Bormans)Information ArchitectCommented:
Of course you can decide what you output here:
           <xsl:otherwise>
                <xsl:value-of select="$Ccount"/><xsl:text> nodes found</xsl:text>
            </xsl:otherwise>
you might be only interested in the <xsl:value-of select="$Ccount"/> :-)
Gertone (Geert Bormans)Information ArchitectCommented:
add
<xsl:output method="text"/>
as the first child of <xsl:stylesheet>
to get rid of the XML declaration
gadkinsAuthor Commented:
Thanks mate.  It's midnight here, so I'm too tired to bother looking just now.  I'll have a decent look in the morning.
gadkinsAuthor Commented:
After minor changes to fit my real XML layout, it worked perfectly.  Thanks very much.  Great work!
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
XML

From novice to tech pro — start learning today.