'XSLT - match with multiple condition (and)

I have the following input

<?xml version="1.0" encoding="UTF-8"?>
<document>
   <body>
        <p>
         <pPr>
            <spacing after="120"/>
            <ind left="357"/>
         </pPr>
         <r>
            <t>Should stay same</t>
         </r>
      </p>
      <p>
         <pPr>
            <pStyle val="ListeAufzhlung"/>
            <spacing after="120"/>
         </pPr>
         <r>
            <t>Liste.Aufzählung</t>
         </r>
      </p>
      <p>
         <pPr>
            <spacing after="120"/>
            <ind left="357"/>
         </pPr>
         <r>
            <t>Shouldl change ind to pStyle</t>
         </r>
      </p>
      <p>
         <pPr>
            <pStyle val="ListeAufzhlung2"/>
            <spacing after="120"/>
         </pPr>
         <r>
            <t>Liste.Aufzählung 2</t>
         </r>
      </p>
   </body>
</document>

My desired outcome:

<?xml version="1.0" encoding="UTF-8"?>
<document>
   <body>
      <p>
         <pPr>
            <spacing after="120"/>
            <ind left="357"/>
         </pPr>
         <r>
            <t>Should stay same</t>
         </r>
      </p>
      <p>
         <pPr>
            <pStyle val="ListeAufzhlung"/>
            <spacing after="120"/>
         </pPr>
         <r>
            <t>Liste.Aufzählung</t>
         </r>
      </p>
      <p>
         <pPr>
            <spacing after="120"/>
            <pStyle val="ListeAufzhlung"/>
         </pPr>
         <r>
            <t>Shouldl change ind to pStyle</t>
         </r>
      </p>
      <p>
         <pPr>
            <pStyle val="ListeAufzhlung2"/>
            <spacing after="120"/>
         </pPr>
         <r>
            <t>Liste.Aufzählung 2</t>
         </r>
      </p>
   </body>
</document>

Logic:

If there is an ind-tag were in the previous p-node is and pStyle with val "ListeAufzhlung", change the ind tag to <pStyle val="ListeAufzhlung"/>. The val can differ too. So if the condition is true, replace the current ind-tag with the pStyle-tag from previous p-tag.

My xslt so far:

<?xml version="1.0"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:strip-space elements="*"/>
<xsl:preserve-space elements="t"/>
<xsl:output method="xml" encoding="UTF-8" indent="yes" omit-xml-declaration="no"/>

       
    <xsl:template match="@* | node()">
        <xsl:copy>
            <xsl:apply-templates select="@*, node()"/>
        </xsl:copy>
    </xsl:template>
    
    <xsl:template match="ind[@left]">
        
    </xsl:template>
</xsl:stylesheet>

Following doesnt work:

<xsl:template match="ind[@left] and ../../p/pPr/pStyle[@val="ListeAufzhlung"]">

Anyone got a good solution for this?



Solution 1:[1]

I think you can check

<xsl:template match="p[pPr/ind[@left]][preceding-sibling::*[1][self::p[pPr/pStyle/@val = 'ListeAufzhlung']]]/pPr/ind">
  <pStyle val="ListeAufzhlung"/>
</xsl:template>

or

<xsl:template match="p[pPr/ind[@left]][preceding-sibling::*[1][self::p[pPr/pStyle/@val]]]/pPr/ind">
  <xsl:copy-of select="ancestor::p/preceding-sibling::*[1]/pPr/pStyle[@val]"/>
</xsl:template>

for the more general case.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Martin Honnen