title: Grouping elements based on a preceding-sibling processing-instruction
body: <p>I am trying to use a key to group <code>&lt;p&gt;</code> elements based on whether they have a specific processing-instruction as a first preceding sibling, but I am having no luck. </p>
  
  <p>For the following example input, I would like each <code>&lt;p&gt;</code> that has a first preceding-sibling processing-instruction that contains “key” to be grouped with its sibling <code>&lt;p&gt;</code> elements that meet the same criteria. Example input:</p>
  
  <pre><code>&lt;root&gt;
      &lt;p&gt;not in key&lt;/p&gt;
      &lt;?samplePI key?&gt;
      &lt;p&gt;start of key; &lt;/p&gt;
      &lt;?samplePI key?&gt;
      &lt;p&gt;in key 1; &lt;/p&gt;
      &lt;?samplePI key?&gt;
      &lt;p&gt;in key 2; &lt;/p&gt;
      &lt;p&gt;Not in key&lt;/p&gt;
      &lt;?samplePI key?&gt;
      &lt;p&gt;start of new key; &lt;/p&gt;
      &lt;?samplePI key?&gt;
      &lt;p&gt;in new key 3;&lt;/p&gt;
  &lt;/root&gt;
  </code></pre>
  
  <p>Example output:</p>
  
  <pre><code>&lt;root&gt;
      &lt;p&gt;not in key&lt;/p&gt;
      &lt;p&gt;start of key; in key 1; in key 2;&lt;/p&gt;
      &lt;p&gt;Not in key&lt;/p&gt;
      &lt;p&gt;start of new key; in new key 3;&lt;/p&gt;
  &lt;/root&gt;
  </code></pre>
  
  <p>An example of what I've got:</p>
  
  <pre><code>&lt;xsl:template match="root"&gt;
          &lt;root&gt;
              &lt;xsl:apply-templates/&gt;
          &lt;/root&gt;
      &lt;/xsl:template&gt;
  
      &lt;xsl:template match="p"&gt;
          &lt;xsl:choose&gt;
              &lt;xsl:when test="preceding-sibling::node()[1][self::processing-instruction()[contains(., 'key')]][preceding-sibling::p[1][(preceding-sibling::node()[1][self::processing-instruction()[contains(., 'key')]])]]"&gt;
  
              &lt;/xsl:when&gt;
              &lt;xsl:when test="preceding-sibling::node()[1][self::processing-instruction()[contains(., 'key')]][preceding-sibling::p[1][not(preceding-sibling::node()[1][self::processing-instruction()[contains(., 'key')]])]]"&gt;
                  &lt;p&gt;&lt;xsl:value-of select="text()"/&gt;
                      &lt;xsl:apply-templates select="key('nodes', generate-id())" mode="groupedParas"/&gt;
                  &lt;/p&gt;
  
              &lt;/xsl:when&gt;
              &lt;xsl:otherwise&gt;
                  &lt;p&gt;&lt;xsl:apply-templates/&gt;&lt;/p&gt;
              &lt;/xsl:otherwise&gt;
          &lt;/xsl:choose&gt;
      &lt;/xsl:template&gt;
  
      &lt;xsl:template match="p" mode="groupedParas"&gt;
          &lt;xsl:apply-templates/&gt;
      &lt;/xsl:template&gt;
  
  
      &lt;xsl:key name="nodes" match="node()[(self::p[preceding-sibling::node()[1][self::processing-instruction()[contains(., 'key')]]])]" use="generate-id((preceding-sibling::p)[last()])"/&gt;
  
      &lt;xsl:template match="text()"&gt;
          &lt;xsl:value-of select="."/&gt;
      &lt;/xsl:template&gt;   
  </code></pre>
  
  <p>Note that I need the help with getting the correct key syntax, as opposed to generating the desired structure. I need to use XSLT 1.0 for this. Any help appreciated.</p>