Search code examples
xmlxsltstylesheet

XSLT: Rename attribute if not exists


I have a lot of XML files that contain attributes with a misspelled value:

<Part id="1">
  <Attribute Name="Colo" Value="Red" />
</Part>

Colo should be Color. Now in some files this has been corrected manually and then both attributes exist:

<Attribute Name="Colo" Value="Red" />
<Attribute Name="Color" Value="Blue" />

I have a XSL transformation that renames the Colo attribute to Color but I have no idea how to avoid that when the corrected attribute already exists.

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

<xsl:template match="Attribute/@Name[. = 'Colo']">
    <xsl:attribute name="Name">
        <xsl:value-of select="'Color'"/>
    </xsl:attribute>
</xsl:template>

How to not rename if there already is the correct attribute?


Solution

  • I think you want to do:

    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="*"/>
    
    <!-- identity transform -->
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
    
    <xsl:template match="Attribute[@Name = 'Colo']">
        <xsl:if test="not(../Attribute[@Name = 'Color'])">
            <Attribute Name="Color" Value="{@Value}" />
        </xsl:if>
    </xsl:template>
    
    </xsl:stylesheet>
    

    This will modify the Attribute element with the misspelled name if it does not have a sibling with the correct name; otherwise it will just remove it.