xsltcruisecontrol

Is it possible in XSLT to select values from a list with a unique identifier


I have some XML Data like this:

<modifications>
  <modification>
    <revision>1</revision>
    <file action="modified">
      <filename>file1.cpp</filename>
    </file>
    <user>steve</user>
    <comment>updating file1 and file2</comment>
  </modification>
  <modification>
    <revision>1</revision>
    <file action="modified">
      <filename>file2.cpp</filename>
    </file>
    <user>steve</user>
    <comment>updating file1 and file2</comment>
  </modification>
  <modification>
    <revision>2</revision>
    <file action="modified">
      <filename>file1.cpp</filename>
    </file>
    <user>rob</user>
    <comment>reverting file1</comment>
  </modification>
</modifications>

I'm using an xsl:variable to select on this data and it then gets output like this:

steve   1   file1.cpp    modified   updating file1 and file2
steve   1   file2.cpp    modified   updating file1 and file2
rob     2   file1.cpp    modified   reverting file1

Is there anyway to only select values with a unique id, in this case the revision? I realize this would mean I'd lose some of the data, specifically the list of modified files, but I'm okay with that. I'd like to see something like this:

steve   1   updating file1 and file2
rob     2   reverting file1

This is for a cruise control log which outputs a separate modification element for every file modified in a revision.


Solution

  • If you only want the data from the first occurrence of a revision number, then it is possible to make an XPath expression to match "modifications, whose revision number appears for the first time":

    modification[not(preceding::revision = revision)]
    

    However, as the above would also match revision tags wherever they appear in the (preceding) xml, you may wish to specify the criteria more exactly to only match "modifications, whose revision number appears for the first time of any preceding modification":

    modification[not(preceding-sibling::modification/revision = revision)]
    

    Here is the complete XML for this:

    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
        <xsl:output method="text" version="1.0" encoding="UTF-8"/>
        <!-- match modification tags with NEW revisions -->
        <xsl:template match="modification[not(preceding-sibling::modification/revision = revision)]">
            <xsl:value-of select="concat(user,'&#9;',revision,'&#9;',comment,'&#13;&#10;')"/>
        </xsl:template>
        <!-- ignore all other text -->
        <xsl:template match="text()"/>
    </xsl:stylesheet>
    

    This produces the desired output:

    steve   1   updating file1 and file2
    rob     2   reverting file1