0

Hi I want to transform my XML with nested elements into flat XML where all nested elements comes in parallel

Input XML :

    <?xml version='1.0' encoding='UTF-8'?>
<Report_Data>
    <Report_Entry>
        <Employee_ID>02159</Employee_ID>
        <Name>ABC, DEF</Name>
        <Citizenship_Countries>United States of America</Citizenship_Countries>
    <National_Identifiers>
        <National_ID_Country>United States of America</National_ID_Country>
        <National_ID_Type_Name>Social Security Number (SSN)</National_ID_Type_Name>
        <National_ID_Unformatted>111111111</National_ID_Unformatted>
    </National_Identifiers>
    <Marital_Status>Married (United States of America)</Marital_Status>
    <Dependents>
        <Relationship>Child</Relationship>
        <Name>Ethan ABC</Name>
        <Age>12</Age>
    </Dependents>
    <Dependents>
        <Relationship>Child</Relationship>
        <Name>Holly ABC</Name>
        <Age>7</Age>
    </Dependents>
</Report_Entry>
<Report_Entry>
    <Employee_ID>04805</Employee_ID>
    <Name>dUMMY, ABC</Name>
    <Citizenship_Countries>United States of America</Citizenship_Countries>
    <National_Identifiers>
        <National_ID_Country>United States of America</National_ID_Country>
        <National_ID_Type_Name>Social Security Number (SSN)</National_ID_Type_Name>
        <National_ID_Unformatted>111111111</National_ID_Unformatted>
    </National_Identifiers>
    <Marital_Status>Married (United States of America)</Marital_Status>
    <Dependents>
        <Relationship>Child</Relationship>
        <Name>QWER dUMMY</Name>
        <Age>6</Age>
    </Dependents>
    <Dependents>
            <Relationship>Child</Relationship>
            <Name>ASDF dUMMY</Name>
            <Age>4</Age>
        </Dependents>
    </Report_Entry>
</Report_Data>

output XML :

<?xml version='1.0' encoding='UTF-8'?>
<Report_Data>
<Report_Entry>
    <Employee_ID>02159</Employee_ID>
    <Name>ABC, DEF</Name>
    <Citizenship_Countries>United States of America</Citizenship_Countries>
    <National_Identifiers_National_ID_Country>United States of America</National_Identifiers_National_ID_Country>
    <National_Identifiers_National_ID_Type_Name>Social Security Number (SSN)</National_Identifiers_National_ID_Type_Name>
    <National_Identifiers_National_ID_Unformatted>111111111</National_Identifiers_National_ID_Unformatted>
    <Marital_Status>Married (United States of America)</Marital_Status>
    <Dependent_Relationship>Child</Dependent_Relationship>
    <Dependent_Name>Ethan ABC</Dependent_Name>
    <Dependent_Age>12</Dependent_Age>
</Report_Entry>
<Report_Entry>
    <Employee_ID>02159</Employee_ID>
    <Name>ABC, DEF</Name>
    <Citizenship_Countries>United States of America</Citizenship_Countries>
    <National_Identifiers_National_ID_Country>United States of America</National_Identifiers_National_ID_Country>
    <National_Identifiers_National_ID_Type_Name>Social Security Number (SSN)</National_Identifiers_National_ID_Type_Name>
    <National_Identifiers_National_ID_Unformatted>111111111</National_Identifiers_National_ID_Unformatted>
    <Marital_Status>Married (United States of America)</Marital_Status>
    <Dependent_Relationship>Child</Dependent_Relationship>
    <Dependent_Name>Holly ABC</Dependent_Name>
    <Dependent_Age>7</Dependent_Age>
</Report_Entry>
<Report_Entry>
    <Employee_ID>04805</Employee_ID>
    <Name>dUMMY, ABC</Name>
    <Citizenship_Countries>United States of America</Citizenship_Countries>
    <National_Identifiers_National_ID_Country>United States of America</National_Identifiers_National_ID_Country>
    <National_Identifiers_National_ID_Type_Name>Social Security Number (SSN)</National_Identifiers_National_ID_Type_Name>
    <National_Identifiers_National_ID_Unformatted>111111111</National_Identifiers_National_ID_Unformatted>
    <Marital_Status>Married (United States of America)</Marital_Status>
    <Dependent_Relationship>Child</Dependent_Relationship>
    <Dependent_Name>QWER dUMMY</Dependent_Name>
    <Dependent_Age>6</Dependent_Age>
</Report_Entry>
<Report_Entry>
    <Employee_ID>04805</Employee_ID>
    <Name>dUMMY, ABC</Name>
    <Citizenship_Countries>United States of America</Citizenship_Countries>
    <National_Identifiers_National_ID_Country>United States of America</National_Identifiers_National_ID_Country>
    <National_Identifiers_National_ID_Type_Name>Social Security Number (SSN)</National_Identifiers_National_ID_Type_Name>
    <National_Identifiers_National_ID_Unformatted>111111111</National_Identifiers_National_ID_Unformatted>
    <Marital_Status>Married (United States of America)</Marital_Status>
    <Dependent_Relationship>Child</Dependent_Relationship>
    <Dependent_Name>ASDF dUMMY</Dependent_Name>
    <Dependent_Age>4</Dependent_Age>
</Report_Entry>
</Report_Data>

Note: My child element is same element with name "Name" under dependent element. So what I want in my output XML is name of dependent Name is to be with different element name like Dependent_Name

0

2 Answers 2

1

Besides your question-title differs from the real thread, i show you one way to solve it. It does use less hardcoded pathes so it is a more generic way.

Whenever a childnode of a child of Report_Entry exists, it will get flatten with the name of parent. I hope you don't need any further deeper levels. [not included in question and solution]

I. XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format">
    <xsl:output method="xml" indent="yes"/>
    <xsl:strip-space elements="Report_Entry National_Identifiers Dependents"/>

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

    <xsl:template match="Report_Data">
        <xsl:copy>
            <xsl:for-each select="Report_Entry/Dependents">
                <xsl:element name="Report_Entry">
                    <xsl:apply-templates select="../*[not(self::Dependents)] | ."/>
                </xsl:element>
            </xsl:for-each>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="Report_Entry/*[*]">
        <xsl:apply-templates />
    </xsl:template>

    <xsl:template match="Report_Entry/*/*">
        <xsl:element name="{concat(name(parent::*), '_', name())}">
            <xsl:apply-templates/>
        </xsl:element>
    </xsl:template>

</xsl:stylesheet>
Sign up to request clarification or add additional context in comments.

Comments

0

Your question is somewhat misleading, because the "flattening" part plays a relatively minor role here. The task of creating a separate entry for each Dependents, with a copy of its ancestor elements, is much more significant.

See if this works for you:

<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:template match="/Report_Data">
    <xsl:copy>
        <xsl:for-each select="Report_Entry/Dependents">
            <Report_Entry>
                <xsl:copy-of select="../Employee_ID | ../Name | ../Citizenship_Countries"/>
                <xsl:for-each select="../National_Identifiers/*">
                    <xsl:element name="National_Identifiers_{name()}">
                        <xsl:value-of select="."/>
                    </xsl:element>
                </xsl:for-each>
                <xsl:copy-of select="../Marital_Status"/>
                <xsl:for-each select="*">
                    <xsl:element name="Dependent_{name()}">
                        <xsl:value-of select="."/>
                    </xsl:element>
                </xsl:for-each>
            </Report_Entry>
        </xsl:for-each>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>

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.