使用XSLT嵌套XML到Flat XML

时间:2015-12-01 20:00:52

标签: xml xslt xslt-1.0 xslt-2.0

我正在尝试将嵌套的XML结构转换为扁平XML,在xslt中使用for-each但是在努力:( 下面是我的源代码和目标,所以使用XSLT的任何输入都将非常受欢迎。

源XML

<LS>    
<dlu fD="2012-06-07" tD="2012-06-13">
        <ULUI uid="uid-1" fAD="2012-06-11" lAD="2012-06-11">
          <LU license="License1" count="1"/>
        </ULUI>
        <ULUI uid="uid-2" fAD="2012-06-10" lAD="2012-06-10">
          <LU license="License1" count="1"/>
        </ULUI>
        <ULUI uid="uid-3" fAD="2012-06-09" lAD="2012-06-09">
          <LU license="License1" count="1"/>
        </ULUI>
        <ULUI uid="uid-4" fAD="2012-06-07" lAD="2012-06-08">
          <LU license="License3" count="1"/>
          <LU license="License4" count="1"/>
        </ULUI>
        <ULUI uid="uid-5" fAD="2012-06-07" lAD="2012-06-08">
          <LU license="License1" count="1"/>
          <LU license="License5" count="1"/>
        </ULUI>
      </dlu>
      <dlu fD="2012-06-14" tD="2012-06-20">
        <ULUI uid="uid-1" fAD="2012-06-14" lAD="2012-06-14">
          <LU license="License1" count="1"/>
        </ULUI>
        <ULUI uid="uid-2" fAD="2012-06-15" lAD="2012-06-20">
          <LU license="License2" count="1"/>
          <LU license="License4" count="1"/>
        </ULUI>
        <ULUI uid="uid-3" fAD="2012-06-16" lAD="2012-06-19">
          <LU license="License1" count="1"/>
          <LU license="License5" count="1"/>
        </ULUI>
        <ULUI uid="uid-4" fAD="2012-06-17" lAD="2012-06-18">
          <LU license="License1" count="1"/>
          <LU license="License3" count="1"/>
        </ULUI>
        <ULUI uid="uid-5" fAD="2012-06-17" lAD="2012-06-18">
          <LU license="License7" count="1"/>
          <LU license="License9" count="1"/>
        </ULUI>
    </dlu>
</LS>

目标XML

<FDLU>
<LU>
<LD_FR_DT>2012-06-07</LD_FR_DT
<LD_TO_DT>2012-06-13</LD_TO_DT>
<LU_UID>uid-1</LU_UID>  
<LU_FA_DT>2012-06-11</LU_FA_DT>
<LU_LA_DT>2012-06-11</LU_LA_DT>
<LU_LICENSE>License1</LU_LICENSE>
<LU_COUNT>1</LU_COUNT>
</LU>
<LU>
<LD_FR_DT>2012-06-07</LD_FR_DT
<LD_TO_DT>2012-06-13</LD_TO_DT>
<LU_UID>uid-2</LU_UID>  
<LU_FA_DT>2012-06-10</LU_FA_DT>
<LU_LA_DT>2012-06-10</LU_LA_DT>
<LU_LICENSE>License1</LU_LICENSE>
<LU_COUNT>1</LU_COUNT>
</LU>
<LU>
<LD_FR_DT>2012-06-07</LD_FR_DT
<LD_TO_DT>2012-06-13</LD_TO_DT>
<LU_UID>uid-4</LU_UID>  
<LU_FA_DT>2012-06-07</LU_FA_DT>
<LU_LA_DT>2012-06-08</LU_LA_DT>
<LU_LICENSE>License3</LU_LICENSE>
<LU_COUNT>1</LU_COUNT>
</LU>
<LU>
<LD_FR_DT>2012-06-07</LD_FR_DT
<LD_TO_DT>2012-06-13</LD_TO_DT>
<LU_UID>uid-4</LU_UID>  
<LU_FA_DT>2012-06-07</LU_FA_DT>
<LU_LA_DT>2012-06-08</LU_LA_DT>
<LU_LICENSE>License4</LU_LICENSE>
<LU_COUNT>1</LU_COUNT>
</LU>
<LU>
<LD_FR_DT>2012-06-07</LD_FR_DT
<LD_TO_DT>2012-06-13</LD_TO_DT>
<LU_UID>uid-5</LU_UID>  
<LU_FA_DT>2012-06-07</LU_FA_DT>
<LU_LA_DT>2012-06-08</LU_LA_DT>
<LU_LICENSE>License1</LU_LICENSE>
<LU_COUNT>1</LU_COUNT>
</LU>
<LU>
<LD_FR_DT>2012-06-07</LD_FR_DT
<LD_TO_DT>2012-06-13</LD_TO_DT>
<LU_UID>uid-5</LU_UID>  
<LU_FA_DT>2012-06-07</LU_FA_DT>
<LU_LA_DT>2012-06-08</LU_LA_DT>
<LU_LICENSE>License5</LU_LICENSE>
<LU_COUNT>1</LU_COUNT>
</LU>
<LD_FR_DT>2012-06-14</LD_FR_DT
<LD_TO_DT>2012-06-20</LD_TO_DT>
<LU_UID>uid-1</LU_UID>  
<LU_FA_DT>2012-06-14</LU_FA_DT>
<LU_LA_DT>2012-06-14</LU_LA_DT>
<LU_LICENSE>License1</LU_LICENSE>
<LU_COUNT>1</LU_COUNT>
</LU>
.....
</FDLU>

所以基本上我需要来自源的每个LU的平行,但我的ULUI&amp; DLU也是无界限的,所以它们可以出现不止一次。 我正在寻找xslt 1.0或2.0版本的解决方案。我开始使用for-each LU然后尝试继续,但我无法处理ULUI和DLU多次出现,并且它们的值只是在一行中结束。

我的努力进展

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xml="http://www.w3.org/XML/1998/namespace" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
     <xsl:output encoding="UTF-8" indent="yes" method="xml"/>
     <xsl:variable name="srcDoc1" select="bpws:getVariableData('XMLVar')"/>
   <xsl:template match="/">
      <xsl:element name="FDLU" namespace="">
<!--         <xsl:for-each select="$srcDoc1/LS/DLU"> -->
<!--            <xsl:for-each select="/DLU/ULUI"> -->
                <xsl:for-each select="$srcDoc1/LS/DLU/ULUI/LU">
                       <xsl:element name="LD_FR_DT" namespace="">
                            <xsl:value-of select="$srcDoc1/LS/DLU/@fD"/>
                         </xsl:element>
                       <xsl:element name="LD_TO_DT" namespace="">
                            <xsl:value-of select="$srcDoc1/LS/DLU/@tD"/>
                         </xsl:element>
                       <xsl:element name="LU_UID" namespace="">
                            <xsl:value-of select="$srcDoc1/LS/DLU/ULUI/@uid"/>
                         </xsl:element>
                       <xsl:element name="LU_FA_DT" namespace="">
                            <xsl:value-of select="$srcDoc1/LS/DLU/ULUI/@fAD"/>
                         </xsl:element>
                       <xsl:element name="LU_LA_DT" namespace="">
                            <xsl:value-of select="$srcDoc1/LS/DLU/ULUI/@lAD"/>
                         </xsl:element>
                       <xsl:element name="LU_LICENSE" namespace="">
                            <xsl:value-of select="@license"/>
                         </xsl:element>
                       <xsl:element name="LU_COUNT" namespace="">
                            <xsl:value-of select="@count"/>
                         </xsl:element>
                      </xsl:element>
<!--                    </xsl:for-each> -->
<!--              </xsl:for-each> -->
           </xsl:for-each>
        </xsl:element>
     </xsl:template>
  </xsl:stylesheet>

1 个答案:

答案 0 :(得分:2)

我认为这是正确的映射...这也可以通过applytemplates轻松完成。

注意:您的示例XML是一个片段,因此我将其包装在外部元素中进行测试。

<xsl:stylesheet
  version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:msxsl="urn:schemas-microsoft-com:xslt"
  exclude-result-prefixes="msxsl"
>
  <xsl:output method="xml" indent="yes"/>

  <xsl:template match="/">
    <FDUL>
      <xsl:for-each select="//LU">
        <LU>
          <LD_FR_DT>
            <xsl:value-of select="../../@fD"/>
          </LD_FR_DT>
          <LD_TO_DT>
            <xsl:value-of select="../../@tD"/>
          </LD_TO_DT>
          <LU_UID>
            <xsl:value-of select="../@uid"/>
          </LU_UID>
          <LU_FA_DT>
            <xsl:value-of select="../@fAD"/>
          </LU_FA_DT>
          <LU_LA_DT>
            <xsl:value-of select="../@lAD"/>
          </LU_LA_DT>
          <LU_LICENSE>
            <xsl:value-of select="@license"/>
          </LU_LICENSE>
          <LU_COUNT>
            <xsl:value-of select="@count"/>
          </LU_COUNT>
        </LU>
      </xsl:for-each>
    </FDUL>
  </xsl:template>
</xsl:stylesheet>