Transfrom XML to CSV with XSLT, correlating elements by attribute values

Solution 1:

Use a key and perhaps just

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  version="2.0"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  exclude-result-prefixes="xs">

  <xsl:param name="types" as="xs:string*" select="'op1', 'op2', 'op3', 'op4'"/>
  
  <xsl:output method="text"/>
  
  <xsl:key name="type" match="measType" use="@p"/>

  <xsl:template match="data">
    <xsl:value-of select="'label', $types" separator=","/>
    <xsl:text>&#10;</xsl:text>
    <xsl:apply-templates select="measValue"/>
  </xsl:template>
  
  <xsl:template match="measValue">
    <xsl:value-of select="@label, r[key('type', @p)[. = $types]]" separator=","/>
    <xsl:text>&#10;</xsl:text>
  </xsl:template>

</xsl:stylesheet>

It will output the right r values though the order is taken from their sequence inside the measValue, not based on the measType order. For your sample it didn't seem to matter.

For the order and with your additional requirement change the value-of to

<xsl:value-of select="@label, for $t in $types return string(r[key('type', @p)[. = $t]])" separator=","/>