1

I have the following XML:

<EMPLOYEE_LIST>
    <EMPLOYEES_01>
        <PERMANENT>
            <EMPID>650000</EMPID>
            <FIRST_NAME>KEITH</FIRST_NAME>
            <MIDDLE_NAME>H</MIDDLE_NAME>
            <LAST_NAME>ROGERS</LAST_NAME>
        </PERMANENT>
        <CONTRACTUAL>
            <EMPID>650001</EMPID>
            <FIRST_NAME>DARRYL</FIRST_NAME>
            <MIDDLE_NAME>Y</MIDDLE_NAME>
            <LAST_NAME>HANNAH</LAST_NAME>
        </CONTRACTUAL>
    </EMPLOYEES_01>
    <EMPLOYEES_02>
        <PERMANENT>
            <EMPID>650002</EMPID>
            <FIRST_NAME>KEITH</FIRST_NAME>
            <MIDDLE_NAME>ROGERS</MIDDLE_NAME>
            <LAST_NAME>H</LAST_NAME>
        </PERMANENT>
        <CONTRACTUAL>
            <EMPID>650003</EMPID>
            <FIRST_NAME>DARRYL</FIRST_NAME>
            <MIDDLE_NAME>HANNAH</MIDDLE_NAME>
            <LAST_NAME>Y</LAST_NAME>
        </CONTRACTUAL>
    </EMPLOYEES_02>
</EMPLOYEE_LIST>

And I am using the following XML to transform it:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="xml" encoding="UTF-8" indent="yes"/>
    <xsl:strip-space elements="*"/>
    <xsl:template match="/EMPLOYEE_LIST">
        <employees>
            <xsl:apply-templates select="EMPLOYEES/node()"/>
        </employees>        
    </xsl:template>    
    <xsl:template match="PERMANENT">
        <permanent>
            <xsl:apply-templates select="*"/>
        </permanent>
    </xsl:template>    
    <xsl:template match="EMPID">
        <emp_id>
            <xsl:value-of select="."/>
        </emp_id>
    </xsl:template>    
    <xsl:template match="FIRST_NAME">
        <f_name>
            <xsl:value-of select="."/>
        </f_name>
    </xsl:template>    
    <xsl:template match="MIDDLE_NAME">
        <m_name>
            <xsl:value-of select="."/>
        </m_name>
    </xsl:template>    
    <xsl:template match="LAST_NAME">
        <l_name>
            <xsl:value-of select="."/>
        </l_name>
    </xsl:template>

    <xsl:template match="CONTRACTUAL">
        <permanent>
            <xsl:apply-templates select="*"/>
        </permanent>
    </xsl:template>    
    <xsl:template match="EMPID">
        <emp_id>
            <xsl:value-of select="."/>
        </emp_id>
    </xsl:template>    
    <xsl:template match="FIRST_NAME">
        <f_name>
            <xsl:value-of select="."/>
        </f_name>
    </xsl:template>    
    <xsl:template match="MIDDLE_NAME">
        <m_name>
            <xsl:value-of select="."/>
        </m_name>
    </xsl:template>    
    <xsl:template match="LAST_NAME">
        <l_name>
            <xsl:value-of select="."/>
        </l_name>
    </xsl:template>
</xsl:stylesheet>

Expecting the converted XML with the following output:

<?xml version="1.0" encoding="UTF-8"?>
<employees>
    <employee>
        <emp_id>650000</emp_id>
        <f_name>KEITH</f_name>
        <m_name>H</m_name>
        <l_name>ROGERS</l_name>
        <type>permanent</type>
        <emp_id>650001</emp_id>
        <f_name>DARRYL</f_name>
        <m_name>Y</m_name>
        <l_name>HANNAH</l_name>
        <type>contractual</type>
        <emp_id>650002</emp_id>
        <f_name>KEITH</f_name>
        <m_name>ROGERS</m_name>
        <l_name>H</l_name>
        <type>permanent</type>
        <emp_id>650003</emp_id>
        <f_name>DARRYL</f_name>
        <m_name>HANNAH</m_name>
        <l_name>Y</l_name>
        <type>contractual</type>
    </employee>
</employees>

so far i haven't been successful at it as i am new to this and any help would be appreciated

thanks

2 Answers 2

1

A shorter and more "push-style" solution: Just adapt slightly my answer to the previous question:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:my="my:my" exclude-result-prefixes="my">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <my:Renames>
  <n old="EMPID" new="emp_id"/>
  <n old="FIRST_NAME" new="f_name"/>
  <n old="MIDDLE_NAME" new="m_name"/>
  <n old="LAST_NAME" new="l_name"/>
  <n old="PERMANENT" new="permanent"/>
  <n old="CONTRACTUAL" new="contractual"/>
 </my:Renames>

 <xsl:variable name="vRenames" select="document('')/*/my:Renames/*"/>

 <xsl:template match="EMPLOYEE_LIST">
  <employees><employee><xsl:apply-templates/></employee></employees>
 </xsl:template>

 <xsl:template match="*/*/*" priority="-1">
     <xsl:element name="{$vRenames[@old = name(current())]/@new}">
       <xsl:apply-templates/>
     </xsl:element>
 </xsl:template>

 <xsl:template match="PERMANENT|CONTRACTUAL">
  <xsl:apply-templates/>
  <type><xsl:value-of select="$vRenames[@old = name(current())]/@new"/></type>
 </xsl:template>
</xsl:stylesheet>

When this transformation is applied to the provided XML document:

<EMPLOYEE_LIST>
    <EMPLOYEES_01>
        <PERMANENT>
            <EMPID>650000</EMPID>
            <FIRST_NAME>KEITH</FIRST_NAME>
            <MIDDLE_NAME>H</MIDDLE_NAME>
            <LAST_NAME>ROGERS</LAST_NAME>
        </PERMANENT>
        <CONTRACTUAL>
            <EMPID>650001</EMPID>
            <FIRST_NAME>DARRYL</FIRST_NAME>
            <MIDDLE_NAME>Y</MIDDLE_NAME>
            <LAST_NAME>HANNAH</LAST_NAME>
        </CONTRACTUAL>
    </EMPLOYEES_01>
    <EMPLOYEES_02>
        <PERMANENT>
            <EMPID>650002</EMPID>
            <FIRST_NAME>KEITH</FIRST_NAME>
            <MIDDLE_NAME>ROGERS</MIDDLE_NAME>
            <LAST_NAME>H</LAST_NAME>
        </PERMANENT>
        <CONTRACTUAL>
            <EMPID>650003</EMPID>
            <FIRST_NAME>DARRYL</FIRST_NAME>
            <MIDDLE_NAME>HANNAH</MIDDLE_NAME>
            <LAST_NAME>Y</LAST_NAME>
        </CONTRACTUAL>
    </EMPLOYEES_02>
</EMPLOYEE_LIST>

the wanted, correct result is produced:

<employees>
   <employee>
      <emp_id>650000</emp_id>
      <f_name>KEITH</f_name>
      <m_name>H</m_name>
      <l_name>ROGERS</l_name>
      <type>permanent</type>
      <emp_id>650001</emp_id>
      <f_name>DARRYL</f_name>
      <m_name>Y</m_name>
      <l_name>HANNAH</l_name>
      <type>contractual</type>
      <emp_id>650002</emp_id>
      <f_name>KEITH</f_name>
      <m_name>ROGERS</m_name>
      <l_name>H</l_name>
      <type>permanent</type>
      <emp_id>650003</emp_id>
      <f_name>DARRYL</f_name>
      <m_name>HANNAH</m_name>
      <l_name>Y</l_name>
      <type>contractual</type>
   </employee>
</employees>
Sign up to request clarification or add additional context in comments.

4 Comments

would your suggestion work if I modify the parent node name from EMPLOYEES_02 to ESTRANGED_02?
@ReggieMiller, Yes, just try it :)
haven't tried it with the entire XML but can you tell me if there is a way to truncate/leave out unwanted elements during transformation? say i'd like to truncate l_name during transformation so that the resulting xml has only f_name/m_name?can that be done within this code?
@ReggieMiller, Sure can, but this is yet another new question :) See my answer to this question: stackoverflow.com/questions/321860/…
1

I'll use Dimitre's answer to your previous question as a base here since it was more concise than mine:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:my="my:my" exclude-result-prefixes="my">
  <xsl:output omit-xml-declaration="yes" indent="yes"/>
  <xsl:strip-space elements="*"/>

  <my:Renames>
    <n old="EMPLOYEES" new="employees"/>
    <n old="EMPID" new="emp_id"/>
    <n old="FIRST_NAME" new="f_name"/>
    <n old="MIDDLE_NAME" new="m_name"/>
    <n old="LAST_NAME" new="l_name"/>
    <n old="PERMANENT" new="permanent"/>
    <n old="CONTRACTUAL" new="contractual"/>
  </my:Renames>

  <xsl:variable name="vRenames" select="document('')/*/my:Renames/*"/>

  <xsl:template match="EMPLOYEE_LIST">
    <employees>
      <employee>
        <xsl:apply-templates select="*/*" />
      </employee>
    </employees>
  </xsl:template>

  <xsl:template match="*/*" priority="-1">
    <xsl:element name="{$vRenames[@old = name(current())]/@new}">
      <xsl:apply-templates/>
    </xsl:element>
  </xsl:template>

  <xsl:template match="PERMANENT|CONTRACTUAL">
    <xsl:apply-templates/>
    <type>
      <xsl:value-of select="$vRenames[@old = name(current())]/@new"/>
    </type>
  </xsl:template>
</xsl:stylesheet>

The new part is this:

  <xsl:template match="EMPLOYEE_LIST">
    <employees>
      <employee>
        <xsl:apply-templates select="*/*" />
      </employee>
    </employees>
  </xsl:template>

When run on your sample input from above, this produces:

<employees>
  <employee>
    <emp_id>650000</emp_id>
    <f_name>KEITH</f_name>
    <m_name>H</m_name>
    <l_name>ROGERS</l_name>
    <type>permanent</type>
    <emp_id>650001</emp_id>
    <f_name>DARRYL</f_name>
    <m_name>Y</m_name>
    <l_name>HANNAH</l_name>
    <type>contractual</type>
    <emp_id>650002</emp_id>
    <f_name>KEITH</f_name>
    <m_name>ROGERS</m_name>
    <l_name>H</l_name>
    <type>permanent</type>
    <emp_id>650003</emp_id>
    <f_name>DARRYL</f_name>
    <m_name>HANNAH</m_name>
    <l_name>Y</l_name>
    <type>contractual</type>
  </employee>
</employees>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.