title: How to test for multiple conditions in previous-sibling in XSLT
body: <p>I have XML data that was extracted from a legacy Lotus Notes application and that has embedded richtext formatting. I am trying to format each block of text based on attributes that appear in a previous sibling. I have XSLT inspired by <a href="https://stackoverflow.com/questions/40051134/how-to-grab-attributes-from-previous-siblings-in-xslt">this response</a> from @Jayvee but it's not working.</p>
  
  <p>This is the XML:</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
  &lt;document&gt;
      &lt;item name="Unordered list"&gt;
          &lt;richtext&gt;
              &lt;pardef/&gt;
              &lt;par def="20"&gt;
                  &lt;run&gt;This is the first &lt;/run&gt;&lt;run&gt;paragraph of the preamble.&lt;/run&gt;
              &lt;/par&gt;
              &lt;par&gt;
                  &lt;run&gt;This is the second paragraph of the &lt;/run&gt;&lt;run&gt;preamble.&lt;/run&gt;
              &lt;/par&gt;
              &lt;pardef id="21" list="unordered"/&gt;
              &lt;par def="21"&gt;
                  &lt;run&gt;This is the &lt;/run&gt;&lt;run&gt;first bullet.&lt;/run&gt;
              &lt;/par&gt;
              &lt;par&gt;
                  &lt;run&gt;This is the second &lt;/run&gt;&lt;run&gt;bullet.&lt;/run&gt;
              &lt;/par&gt;
              &lt;par def="20"&gt;
                  &lt;run&gt;This is the first &lt;/run&gt;&lt;run&gt;paragraph of the conclusion.&lt;/run&gt;
              &lt;/par&gt;
              &lt;par&gt;
                  &lt;run&gt;This is the second paragraph of the &lt;/run&gt;&lt;run&gt;conclusion.&lt;/run&gt;
              &lt;/par&gt;
          &lt;/richtext&gt;
      &lt;/item&gt;
      &lt;item name="Ordered list"&gt;
          &lt;richtext&gt;
              &lt;pardef/&gt;
              &lt;par def="20"&gt;
                  &lt;run&gt;This is the first &lt;/run&gt;&lt;run&gt;paragraph of the preamble.&lt;/run&gt;
              &lt;/par&gt;
              &lt;par&gt;
                  &lt;run&gt;This is the second paragraph of the &lt;/run&gt;&lt;run&gt;preamble.&lt;/run&gt;
              &lt;/par&gt;
              &lt;pardef id="46" list="ordered"/&gt;
              &lt;par def="46"&gt;
                  &lt;run&gt;This is the &lt;/run&gt;&lt;run&gt;first numbered item.&lt;/run&gt;
              &lt;/par&gt;
              &lt;par&gt;
                  &lt;run&gt;This is the another &lt;/run&gt;&lt;run&gt;numbered item.&lt;/run&gt;
              &lt;/par&gt;
              &lt;par def="20"&gt;
                  &lt;run&gt;This is the first &lt;/run&gt;&lt;run&gt;paragraph of the conclusion.&lt;/run&gt;
              &lt;/par&gt;
              &lt;par&gt;
                  &lt;run&gt;This is the second paragraph of the &lt;/run&gt;&lt;run&gt;conclusion.&lt;/run&gt;
              &lt;/par&gt;
          &lt;/richtext&gt;
      &lt;/item&gt;
  &lt;/document&gt;
  </code></pre>
  
  <p>This is the desired output:</p>
  
  <pre><code>&lt;html&gt;
    &lt;body&gt;
       &lt;table border="1"&gt;
          &lt;tr&gt;
             &lt;td&gt;Unordered list&lt;/td&gt;
             &lt;td&gt;
                &lt;p&gt;This is the first paragraph of the preamble.&lt;/p&gt;
                &lt;p&gt;This is the second paragraph of the preamble.&lt;/p&gt;
                &lt;ul&gt;
                   &lt;li&gt;This is the first bullet.&lt;/li&gt;
                   &lt;li&gt;This is the second bullet.&lt;/li&gt;
                &lt;/ul&gt;
                &lt;p&gt;This is the first paragraph of the conclusion.&lt;/p&gt;
                &lt;p&gt;This is the second paragraph of the conclusion.&lt;/p&gt;
             &lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
             &lt;td&gt;Ordered list&lt;/td&gt;
             &lt;td&gt;
                &lt;p&gt;This is the first paragraph of the preamble.&lt;/p&gt;
                &lt;p&gt;This is the second paragraph of the preamble.&lt;/p&gt;
                &lt;ol&gt;
                   &lt;li&gt;This is the first numbered item.&lt;/li&gt;
                   &lt;li&gt;This is the another numbered item.&lt;/li&gt;
                &lt;/ol&gt;
                &lt;p&gt;This is the first paragraph of the conclusion.&lt;/p&gt;
                &lt;p&gt;This is the second paragraph of the conclusion.&lt;/p&gt;
             &lt;/td&gt;
          &lt;/tr&gt;
       &lt;/table&gt;
    &lt;/body&gt;
  </code></pre>
  
  <p></p>
  
  <p>This is the XSLT:</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="utf-8"?&gt;
  &lt;xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"&gt;
      &lt;xsl:output indent="yes"/&gt;
  
      &lt;xsl:template match="/*"&gt;
          &lt;html&gt;
              &lt;body&gt;
                  &lt;table border="1"&gt;
                          &lt;xsl:apply-templates/&gt;
                  &lt;/table&gt;
              &lt;/body&gt;
          &lt;/html&gt;
      &lt;/xsl:template&gt;
  
      &lt;xsl:template match="item"&gt;
          &lt;tr&gt;
              &lt;td&gt;&lt;xsl:value-of select="@name"/&gt;&lt;/td&gt;
              &lt;td&gt;
                  &lt;xsl:apply-templates/&gt;
              &lt;/td&gt;
          &lt;/tr&gt;
      &lt;/xsl:template&gt;
  
      &lt;xsl:template match="par"&gt;
  
          &lt;xsl:choose&gt;
          &lt;xsl:when test="preceding-sibling::pardef[@list] = 'unordered' and preceding-sibling::par[@def][1][@def] != preceding-sibling::pardef[@id]"&gt;&lt;xsl:text disable-output-escaping="yes"&gt;&amp;lt;/ul&amp;gt;&lt;/xsl:text&gt;&lt;/xsl:when&gt;
          &lt;xsl:when test="preceding-sibling::pardef[@list] = 'ordered' and preceding-sibling::par[@def][1][@def] != preceding-sibling::pardef[@id]"&gt;&lt;xsl:text disable-output-escaping="yes"&gt;&amp;lt;/ol&amp;gt;&lt;/xsl:text&gt;&lt;/xsl:when&gt;  
          &lt;/xsl:choose&gt;
  
          &lt;xsl:choose&gt;
  
              &lt;xsl:when test="@def=preceding-sibling::pardef[@id] or (not(@def) and preceding-sibling::par[@def][1][@def=preceding-sibling::pardef[@id]])"&gt;    
                  &lt;xsl:choose&gt;
                      &lt;xsl:when test="preceding-sibling::pardef[@list] = 'unordered' and preceding-sibling::par[@def][1][@def] = preceding-sibling::pardef[@id]"&gt;&lt;xsl:text disable-output-escaping="yes"&gt;&amp;lt;ul&amp;gt;&lt;/xsl:text&gt;&lt;/xsl:when&gt;
                      &lt;xsl:when test="preceding-sibling::pardef[@list] = 'ordered' and preceding-sibling::par[@def][1][@def] = preceding-sibling::pardef[@id]"&gt;&lt;xsl:text disable-output-escaping="yes"&gt;&amp;lt;ol&amp;gt;&lt;/xsl:text&gt;&lt;/xsl:when&gt;  
                  &lt;/xsl:choose&gt;
                  &lt;li&gt;
                      &lt;xsl:for-each select="run"&gt;
                          &lt;xsl:value-of select="text()" separator=""/&gt;
                      &lt;/xsl:for-each&gt;
                  &lt;/li&gt;   
              &lt;/xsl:when&gt;
  
              &lt;xsl:when test="not(@def=preceding-sibling::pardef[@id])"&gt;
                  &lt;p&gt;
                      &lt;xsl:for-each select="run"&gt;
                          &lt;xsl:value-of select="text()" separator=""/&gt;
                      &lt;/xsl:for-each&gt;
                  &lt;/p&gt;    
              &lt;/xsl:when&gt;     
  
          &lt;/xsl:choose&gt;   
  
      &lt;/xsl:template&gt;
  &lt;/xsl:stylesheet&gt;
  </code></pre>