【问题标题】:How to transform Nested XML elements to flat XML如何将嵌套 XML 元素转换为平面 XML
【发布时间】:2016-11-03 03:17:16
【问题描述】:

您好,我想将带有嵌套元素的 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>

注意:我的子元素与从属元素下的名称为 "Name" 的元素相同。所以我在输出 XML 中想要的是依赖名称的名称是使用不同的元素名称,例如 Dependent_Name

【问题讨论】:

    标签: xml xslt xslt-2.0


    【解决方案1】:

    除了您的问题标题与实际线程不同之外,我向您展示了一种解决方法。它确实使用较少的硬编码路径,因此它是一种更通用的方式。

    只要存在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>
    

    【讨论】:

      【解决方案2】:

      您的问题有些误导,因为“扁平化”部分在这里起着相对次要的作用。为每个 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>
      

      【讨论】:

        猜你喜欢
        • 2011-07-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-07-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多