Matt Furr
Matt Furr

Reputation: 53

XPath 1.0: List distinct values with number of their occurrences

I'm generating a report that pulls information from an XML file.

<?xml version="1.0" encoding="UTF-8"?>
<JoinedRoot>
    <FlexoPlateReport>
        <Device>A</Device>
    </FlexoPlateReport>
    <FlexoPlateReport>
        <Device>B</Device>
    </FlexoPlateReport>
    <FlexoPlateReport>
        <Device>A</Device>
    </FlexoPlateReport>
    <FlexoPlateReport>
        <Device>C</Device>
    </FlexoPlateReport>
    <FlexoPlateReport>
        <Device>C</Device>
    </FlexoPlateReport>
    <FlexoPlateReport>
        <Device>B</Device>
    </FlexoPlateReport>
    <FlexoPlateReport>
        <Device>A</Device>
    </FlexoPlateReport>
</JoinedRoot>

Basically, what I have done so far is put together an XPath Expression that will list the distinct devices. There are three devices in the XML above (A, B, and C). Below is the XPath Expression.

/JoinedRoot/FlexoPlateReport[not( Device/text()=preceding-sibling::FlexoPlateReport/Device/text())]/Device/text()

I'm limited to XPath 1.0, otherwise I would use the distinct-values() function. Next what I would like to do is return the count for each of devices listed in the first XPath Expression. For example, the XML from above would give me the following counts:

A: 3
B: 2
C: 2

Is it possible to return both the names and count in a single expression? If not, is there an XPath Expression that would return just the counts for each of the distinct devices. I will never know how many distinct devices are in the report or what the values are for the Device element. Therefore, I cannot simply write count() functions for a particular device name.

Thanks in advance!

Upvotes: 2

Views: 830

Answers (1)

Thomas W
Thomas W

Reputation: 15391

If you're restricted to XPath 1.0, that's not possible with a single query. You'd need a two-pass process. If you're programmatically making these queries, use the respective programming language (XSLT, PHP, JavaScript) to trigger counting queries based on the results of the first query.

count(/JoinedRoot/FlexoPlateReport/Device[.='A'])

Upvotes: 1

Related Questions