Home > Software design >  How to add Attribute as well as child element at same time for XML using XSLT
How to add Attribute as well as child element at same time for XML using XSLT

Time:04-09

I am new to XSLT I am trying to perform below operations(adding ID as child element as well pattern as attribute on package) on XML. I have provided expected output as well as my XSLT. Can you please provide me generic solution as I have nested package nodes in xml for simplicity I have provided simple XML.As of now I am able to add only attribute change(pattern) on my xml my ID related changes(child element) is getting overridden.

Input XML

<Package ID="b9e05dea-80dc-436b-bea6-497161b08342" xsi:type="Mobile_Plan_Package_Template" BusinessID="000126" Path="/Package/Product/Launch_Entity" Version="1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Name>SuperCare Plan</Name>
</Package>

Expected Output from XSLT

<Package ID="b9e05dea-80dc-436b-bea6-497161b08342" pattern="Package" xsi:type="Mobile_Plan_Package_Template" BusinessID="000126" Path="/Package/Product/Launch_Entity" Version="1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Name>SuperCare Plan</Name>
<ID>b9e05dea-80dc-436b-bea6-497161b08342</ID>
</Package>

XSLT

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
  exclude-result-prefixes="xsi">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" />
    
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
    
    <!--To Add IDs in all nodes-->
    <xsl:template match="*[@ID]" >      
            <xsl:copy>  
            <xsl:apply-templates select="@*|node()"/>
            <ID>
                <xsl:value-of select="current()/@ID" />
            </ID>
            
           </xsl:copy>
                    
    </xsl:template>
    <!--To Add IDs in all nodes-->

    
<!--To Add Attributes in package node-->
   <xsl:template match="*[local-name() = 'Package']">

        <xsl:copy>
            <xsl:attribute name="pattern">
                <xsl:value-of select="local-name()"/>
            </xsl:attribute>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>

    </xsl:template>
<!--To Add Attributes in package node-->


</xsl:stylesheet>

Thanks for your help in advance

CodePudding user response:

AFAICT, this should work for you:

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="Package">
    <xsl:copy>
        <xsl:attribute name="pattern">
            <xsl:value-of select="local-name()"/>
        </xsl:attribute>
        <xsl:apply-templates select="@*|node()"/>
        <ID>
            <xsl:value-of select="@ID"/>
        </ID>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>
  • Related