如何将嵌套的XML元素转换为平面XML

时间:2016-11-03 03:17:16

标签: xml xslt xslt-2.0

您好我想将嵌套元素的XML转换为平面XML,其中所有嵌套元素并行

输入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>

输出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>

注意:我的子元素是依赖元素下名称“名称”的元素。所以我想要的输出XML是依赖名称的名称是不同的元素名称,如 Dependent_Name

2 个答案:

答案 0 :(得分:1)

除了你的问题标题与真正的主题不同,我向你展示了一种解决方法。它使用较少硬编码的pathes,因此它是一种更通用的方式。

每当Report_Entry的孩子的子节点存在时,它就会被父母的名字弄平。我希望你不再需要更深层次。 [不包括在问题和解决方案中]

<强>予。 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>

答案 1 :(得分:0)

你的问题有点误导,因为&#34;扁平化&#34;部分在这里起着相对次要的作用。为每个Dependents创建一个单独的条目以及其祖先元素的副本的任务更为重要。

看看这是否适合你:

<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>