Search code examples
xslttransformparentexpand

XSLT: How to expand child element to have extra parent element


I am trying to transform XML into another XML file but unsuccessfully changing a flat element into an expanded element.

The output should be identical except DateOfBirth should be changed to:

<DateOfBirth>
  <FullDate xmlns="cds_dt">1966-02-11</FullDate>
</DateOfBirth>

Here are the input files I am using:

Input
*****
<?xml version="1.0" encoding="utf-8"?>
<RootRec xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="cds">
  <MyRecord>
    <Demographics>
      <Names>
        <LegalName namePurpose="L" xmlns="cds_dt">
          <FirstName>
            <Part>Jason</Part>
            <PartType>GIV</PartType>
          </FirstName>
          <LastName>
            <Part>Smith</Part>
            <PartType>FAMC</PartType>
          </LastName>
          <OtherName>
            <Part>Lauren</Part>
            <PartType>GIV</PartType>
          </OtherName>
        </LegalName>
      </Names>
      <DateOfBirth>1966-02-11</DateOfBirth>
    <Demographics>
  <MyRecord>    
</RootRec>


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

  <!--Identity Template. This will copy everything as-is.--> 
  <xsl:template match="node()|@*"> 
    <xsl:copy> 
      <xsl:apply-templates select="node()|@*"/> 
    </xsl:copy> 
  </xsl:template> 

 <!--expand "DateOfBirth" element to /DateOfBirth/FullDate element.--> 
  <xsl:template match="RootRec/MyRecord/Demographics/DateOfBirth"> 
    <DateOfBirth> 
      <FullDate><xsl:value-of select="DateOfBirth"/></FullDate>
    </DateOfBirth> 
  </xsl:template> 
</xsl:stylesheet>

Solution

  • This transformation:

    <xsl:stylesheet version="1.0"
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
     xmlns:x="cds">
     <xsl:output omit-xml-declaration="yes" indent="yes"/>
     <xsl:strip-space elements="*"/>
    
     <xsl:template match="node()|@*">
      <xsl:copy>
       <xsl:apply-templates select="node()|@*"/>
      </xsl:copy>
     </xsl:template>
    
     <xsl:template match="x:DateOfBirth/text()">
      <xsl:element name="FullDate" xmlns="cds_dt"><xsl:value-of select="."/></xsl:element>
     </xsl:template>
    </xsl:stylesheet>
    

    when applied on the provided (corrected to be made wellformed) XML document:

    <RootRec
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns="cds">
        <MyRecord>
            <Demographics>
                <Names>
                    <LegalName namePurpose="L" xmlns="cds_dt">
                        <FirstName>
                            <Part>Jason</Part>
                            <PartType>GIV</PartType>
                        </FirstName>
                        <LastName>
                            <Part>Smith</Part>
                            <PartType>FAMC</PartType>
                        </LastName>
                        <OtherName>
                            <Part>Lauren</Part>
                            <PartType>GIV</PartType>
                        </OtherName>
                    </LegalName>
                </Names>
                <DateOfBirth>1966-02-11</DateOfBirth>
            </Demographics>
        </MyRecord>
    </RootRec>
    

    produces the wanted, correct result:

    <RootRec xmlns="cds" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
       <MyRecord>
          <Demographics>
             <Names>
                <LegalName xmlns="cds_dt" namePurpose="L">
                   <FirstName>
                      <Part>Jason</Part>
                      <PartType>GIV</PartType>
                   </FirstName>
                   <LastName>
                      <Part>Smith</Part>
                      <PartType>FAMC</PartType>
                   </LastName>
                   <OtherName>
                      <Part>Lauren</Part>
                      <PartType>GIV</PartType>
                   </OtherName>
                </LegalName>
             </Names>
             <DateOfBirth>
                <FullDate xmlns="cds_dt">1966-02-11</FullDate>
             </DateOfBirth>
          </Demographics>
       </MyRecord>
    </RootRec>
    

    Explanation: Overriding the identity rule.