Home > OS >  change xml element and attribute names to camelCase
change xml element and attribute names to camelCase

Time:04-25

i am new to XSLT and am wondering if it is possible to convert XML element and attribute names to camel case ?

My XML payload is like the below :

<?xml version="1.0" encoding="utf8" ?>
<Output>
    <Error>
        <Status>0</Status>
        <Details>No errors</Details>
    </Error>
    <Synopsis>
        <Count>451</Count>
    </Synopsis>
    <BankAccounts>
        <BankAccount AcctNo="103" CustName="Frank" BalanceAmount="" Inactive="N" NoOfAccounts="1" >
            <Addresses>
                <Address>ABC</Address>
                <Address>XYZ</Address>
            </Addresses>
        </BankAccount>
        <BankAccount AcctNo="101" CustName="Jane" BalanceAmount="10005" Inactive="N" NoOfAccounts="1" >
            <Addresses>
                <Address>LMN</Address>
                <Address>QWE</Address>
            </Addresses>
        </BankAccount>
        
    </BankAccounts>
</Output>

Unfortunately i dont have anything to show as i am stumped on how to go about it .... thanks

CodePudding user response:

XSLT, direct approach

You can inline firstChar variables, I've introduced them for readability.

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="xs"
    version="1.0">
    
    <xsl:output method="xml" indent="yes"/>
    
    <!--elements-->
    <xsl:template match="node()">
        
        <xsl:choose>
            
            <!--elements-->
            <xsl:when test="name() != ''">
                <xsl:variable name="firstChar" select="translate(substring(name(),1,1),'ABCDEFGHIJKLMNOPQRSTUWXYZ','abcdefghijklmnopqrstuwxyz')"/>
                <xsl:element name="{concat($firstChar, substring(name(),2))}">            
                    <xsl:apply-templates select="@*|node()"/>    
                </xsl:element>        
            </xsl:when>
            
            <!--values-->
            <xsl:otherwise>
                <xsl:copy-of select="."/>
            </xsl:otherwise>
        </xsl:choose>
        
    </xsl:template>
    
    <!--attributes-->
    <xsl:template match="@*">
        <xsl:variable name="firstChar" select="translate(substring(name(),1,1),'ABCDEFGHIJKLMNOPQRSTUWXYZ','abcdefghijklmnopqrstuwxyz')"/>
        <xsl:attribute name="{concat($firstChar, substring(name(),2))}">
            <xsl:value-of select="."/>
        </xsl:attribute>
    </xsl:template>
    
</xsl:stylesheet>

XSLT 2, named template for converting a string into camelCase

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="xs"
    version="1.0">
    
    <xsl:output method="xml" indent="yes"/>
    
    <!--elements-->
    <xsl:template match="node()">
        
        <xsl:choose>
            
            <!--elements-->
            <xsl:when test="name() != ''">                
                
                <xsl:variable name="newName">
                    <xsl:call-template name="toCamelCase">
                        <xsl:with-param name="value" select="./name()"/>
                    </xsl:call-template>
                </xsl:variable>                
                
                <xsl:element name="{$newName}">            
                    <xsl:apply-templates select="@*|node()"/>    
                </xsl:element>        
            </xsl:when>
            
            <!--values-->
            <xsl:otherwise>
                <xsl:copy-of select="."/>
            </xsl:otherwise>
        </xsl:choose>
        
    </xsl:template>
    
    <!--attributes-->
    <xsl:template match="@*">
        
        <xsl:variable name="newName">
            <xsl:call-template name="toCamelCase">
                <xsl:with-param name="value" select="./name()"/>
            </xsl:call-template>
        </xsl:variable>                
        
        <xsl:attribute name="{$newName}">
            <xsl:value-of select="."/>
        </xsl:attribute>
    </xsl:template>
    
    <!--named template that converts a string into camel case-->
    <xsl:template name="toCamelCase">
        <xsl:param name="value"/>
        <xsl:variable name="firstChar" select="translate(substring($value,1,1),'ABCDEFGHIJKLMNOPQRSTUWXYZ','abcdefghijklmnopqrstuwxyz')"/>
        <xsl:value-of select="concat($firstChar, substring($value,2))"/>
    </xsl:template>
    
</xsl:stylesheet>

Output

<?xml version="1.0" encoding="UTF-8"?>
<output>
    <error>
        <status>0</status>
        <details>No errors</details>
    </error>
    <synopsis>
        <count>451</count>
    </synopsis>
    <bankAccounts>
        <bankAccount acctNo="103"
                   custName="Frank"
                   balanceAmount=""
                   inactive="N"
                   noOfAccounts="1">
            <addresses>
                <address>ABC</address>
                <address>XYZ</address>
            </addresses>
        </bankAccount>
        <bankAccount acctNo="101"
                   custName="Jane"
                   balanceAmount="10005"
                   inactive="N"
                   noOfAccounts="1">
            <addresses>
                <address>LMN</address>
                <address>QWE</address>
            </addresses>
        </bankAccount>
        
    </bankAccounts>
</output>

CodePudding user response:

For XSLT 2/3 I would use the identity transformation plus templates matching element and attribute nodes that change the first letter using lower-case:

<xsl:template match="*">
  <xsl:element name="{prefix-from-QName(node-name())}{}{lower-case(substring(local-name(), 1, 1))}{substring(local-name(), 2)}">
    <xsl:apply-templates select="@*, node()"/>
  </xsl:element>
</xsl:template>

<xsl:template match="@*">
  <xsl:attribute name="{prefix-from-QName(node-name())}{}{lower-case(substring(local-name(), 1, 1))}{substring(local-name(), 2)}" select="."/>
</xsl:template>
  • Related