xslt for flat to hierarchical xml

时间:2013-03-29 05:20:31

标签: xslt

我正在尝试创建一个将平面结构(带有父/子id)映射到层次结构的转换。 我在下面列出了一个简单的例子。实际数据有4000多个元素。我没有关于最大深度的数据,转换应该能够递归到n级。 感谢这篇文章xslt-flat-to-hierarchical我试图按照我的情况来遵循它的模式。不幸的是,它没有递归!任何帮助将非常感激! 谢谢!

这是源xml ....

<?xml version='1.0' encoding='UTF-8'?> 
<asx:abap xmlns:asx='http://www.sap.com/abapxml' version='1.0'>
  <asx:values>
    <SYSINFO>
      <SERVER_NAME>sapserver</SERVER_NAME>
      <SYSTEM_ID>EC2</SYSTEM_ID>
    </SYSINFO>
    <CT/>
    <PACKAGES/>
    <SW_COMPONENTS/>
    <APP_COMPONENTS>
      <item>
        <ID>000001</ID>
        <NAME>HLA0009999</NAME>
        <PARENT>000000</PARENT>
        <CHILD>000002</CHILD>
        <TEXT>SAP</TEXT>
        <TEXT4>Application Components</TEXT4>
      </item>
      <item>
        <ID>000002</ID>
        <NAME>ABA0000311</NAME>
        <PARENT>000001</PARENT>
        <CHILD>000003</CHILD>
        <TEXT>AP</TEXT>
        <TEXT4>Application Platform</TEXT4>
      </item>
      <item>
        <ID>000003</ID>
        <NAME>KPE0000001</NAME>
        <PARENT>000002</PARENT>
        <CHILD>000000</CHILD>
        <TEXT>AP-PPE</TEXT>
        <TEXT4>Integrated Product and Process Engineering</TEXT4>
      </item>
      <item>
        <ID>000004</ID>
        <NAME>S6D0000006</NAME>
        <PARENT>000002</PARENT>
        <CHILD>000005</CHILD>
        <TEXT>AP-CME</TEXT>
        <TEXT4>Classification System (New)</TEXT4>
      </item>
      <item>
        <ID>000005</ID>
        <NAME>S6D0000007</NAME>
        <PARENT>000004</PARENT>
        <CHILD>000000</CHILD>
        <TEXT>AP-CME-CHR</TEXT>
        <TEXT4>Characteristic</TEXT4>
      </item>
    </APP_COMPONENTS>
  </asx:values>
</asx:abap>

这是所需的xml

<?xml version='1.0' encoding='UTF-8'?> 
    <SYSINFO>
      <SERVER_NAME>sapserver</SERVER_NAME>
      <SYSTEM_ID>EC2</SYSTEM_ID>
    </SYSINFO>
    <CT/>
    <PACKAGES/>
    <SW_COMPONENTS/>
    <APP_COMPONENTS>
      <APP_COMPONENT NR="000001" ID="HLA0009999" NAME="SAP" DESCRIPTION="Application Components" >
          <APP_COMPONENT NR="000002" ID="ABA0000311" NAME="AP" DESCRIPTION="Application Platform" >
              <APP_COMPONENT NR="000003" ID="KPE0000001" NAME="AP-PP3" DESCRIPTION="Integrated Product and Process Engineering" >
                 <APP_COMPONENT NR="000004" ID="S6D0000006" NAME="AP-CME" DESCRIPTION="Classification System (New)" >
                     <APP_COMPONENT NR="000005" ID="S6D0000007" NAME="AP-CME-CHR" DESCRIPTION="Characteristic" >
                     </APP_COMPONENT>
                 </APP_COMPONENT>
              </APP_COMPONENT>
          </APP_COMPONENT>
       </APP_COMPONENT>
    </APP_COMPONENTS>

以下是我尝试使用的转换:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://tempuri.org/COCA" version="1.0">

    <xsl:output indent="yes"/>

    <xsl:key name="sons" match="item" use="PARENT"/>
    <xsl:param name="maxLevels">999</xsl:param>

    <xsl:template match="APP_COMPONENTS">
        <APP_COMPONENT_H>
            <APP_COMPONENTS>
                <xsl:apply-templates select="key('sons', 0)"/>
            </APP_COMPONENTS>
        </APP_COMPONENT_H>
    </xsl:template>

    <xsl:template match="item">
        <xsl:param name="level">1</xsl:param>
        <xsl:if test="$level &lt;= $maxLevels">
            <APP_COMPONENT NR="{ID}" ID="{NAME}" NAME="{TEXT}" DESCRIPTION="{TEXT4}" >
                <APP_COMPONENTS>
                    <xsl:apply-templates select="key('sons', ID)">
                        <xsl:with-param name="level" select="$level  + 1"/>
                    </xsl:apply-templates>
                </APP_COMPONENTS>
            </APP_COMPONENT>
        </xsl:if>
    </xsl:template>
</xsl:stylesheet>

1 个答案:

答案 0 :(得分:0)

我认为问题在于您的初始应用模板

 <xsl:apply-templates select="key('sons', 0)"/>

查看XML, ID PARENT 元素的格式为“000000”,因此XSLT在这里进行字符串比较。

您可以尝试做的是将初始应用模板更改为此

<xsl:apply-templates select="key('sons', '000000')"/>

或者,要进行数字比较,请像这样定义您的密钥

<xsl:key name="sons" match="item" use="number(PARENT)"/>

然后当你使用密钥时,你就这样做了

<xsl:apply-templates select="key('sons', number(ID))">