Home > Net >  XSL: change attribute value of an element whose parent element attribute has a specific value
XSL: change attribute value of an element whose parent element attribute has a specific value

Time:02-10

I want to modify an XML file created by Tableau using an XSL transformation.

What I need is to change the formula value of the calculation element only if the parent element has the value "ifShow" in the caption attribute.

my XML is of the form:

<?xml version='1.0' encoding='utf-8' ?>
<!-- build 20212.21.1112.1433 -->
<workbook source-build='2021.2.5 (20212.21.1112.1433)' source-platform='win' version='18.1' xml:base='https://tableau.company.com' xmlns:user='http://www.tableausoftware.com/xml/user'>
  <datasources>
    <datasource caption='V_Tableau_CommercialLayer' inline='true' name='sqlproxy' version='18.1'>
      <column caption='Month' datatype='string' name='[Calculation_36]' role='dimension' type='nominal'>
        <calculation class='tableau' formula='no change' />
      </column>
      <column caption='ifShow' datatype='string' name='[Calculation_40]' role='dimension' type='nominal'>
        <calculation class='tableau' formula='old code' />
      </column>
     </datasource>
  </datasources>
</workbook>

Desired output:

<?xml version='1.0' encoding='utf-8' ?>
<!-- build 20212.21.1112.1433 -->
<workbook source-build='2021.2.5 (20212.21.1112.1433)' source-platform='win' version='18.1' xml:base='https://tableau.company.com' xmlns:user='http://www.tableausoftware.com/xml/user'>
  <datasources>
    <datasource caption='V_Tableau_CommercialLayer' inline='true' name='sqlproxy' version='18.1'>
      <column caption='Month' datatype='string' name='[Calculation_36]' role='dimension' type='nominal'>
        <calculation class='tableau' formula='no change' />
      </column>
      <column caption='ifShow' datatype='string' name='[Calculation_40]' role='dimension' type='nominal'>
        <calculation class='tableau' formula='new code' />
      </column>
     </datasource>
  </datasources>
</workbook>

The XSL I am using is:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
    <xsl:param name="pNewFormula" select="'new code'"/>
    <xsl:template match="node()|@*">
        <xsl:copy>
            <xsl:apply-templates select="node()|@*"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="column/@caption[. ='ifShow']/calculation">
        <xsl:attribute name="formula">
            <xsl:value-of select="$pNewFormula"/>
        </xsl:attribute>    
    </xsl:template>
</xsl:stylesheet>

However, this doesn't work and I do not know how to access the child node of the element column

Thank you very much for your support!

CodePudding user response:

How about:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:param name="pNewFormula" select="'new code'"/>

<!-- identity transform -->
<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="column[@caption='ifShow']/calculation/@formula">
    <xsl:attribute name="formula">
        <xsl:value-of select="$pNewFormula"/>
    </xsl:attribute>    
</xsl:template>

</xsl:stylesheet>
  • Related