XSLT创建嵌套文件并将顶级元素id复制到子级

时间:2016-07-18 09:00:02

标签: xml xslt

继我之前的question后,我意识到我需要在每个子记录中都有一个顶级元素id和title的副本,并将它们组织成一个嵌套结构。所以我理想的最终结果如下:

    <?xml version="1.0" encoding="UTF-8"?>
<table name="ecatalogue">
   <collection>
      <tuple>
         <atom name="irn">2470</atom>
         <atom name="EADUnitID"/>
         <atom name="EADUnitTitle">Parent title</atom>
         <atom name="EADLevelAttribute"/>
         <tuple name="children">
            <tuple>
               <atom name="irn">5416</atom>
               <atom name="EADUnitID"/>
               <atom name="EADUnitTitle"/>
               <atom name="Parent_irn">2470</atom>
               <atom name="Parent_title">Parent title</atom>
            </tuple>
            <tuple>
               <atom name="irn">7</atom>
               <atom name="EADUnitID"/>
               <atom name="EADUnitTitle"/>
               <atom name="Parent_irn">2470</atom>
               <atom name="Parent_title">Parent title</atom>
               <tuple name="children">
                  <tuple>
                     <atom name="irn">8</atom>
                     <atom name="ObjectType"/>
                     <atom name="EADLevelAttribute"/>
                     <atom name="EADUnitID"/>
                     <atom name="EADUnitTitle"/>
                     <atom name="Parent_irn">2470</atom>
                     <atom name="Parent_title">Parent title</atom>
                  </tuple>
               </tuple>
            </tuple>
         </tuple>
      </tuple>
   </collection>
</table>

我自己试图这样做,但我找不到编辑现有XSLT的方法来让我这样做。最后,我尝试编写另一个XSLT,它将覆盖第一个结果并将父irn和title复制到其子节点。将其应用于小型数据集似乎工作正常,但是在较大的数据集上它只是挂起:

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="ISO-8859-1" indent="yes"/>

<xsl:strip-space elements="*"/>


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

<xsl:template match="collection/record">    
    <record>
        <xsl:apply-templates select=" @* | node()"/>
        <tuple name="top_record">
            <xsl:apply-templates select="atom[@name='irn']"/>
            <xsl:apply-templates select="atom[@name='EADUnitTitle']"/>
        </tuple>
    </record>    
</xsl:template>

<xsl:template match="tuple[@name='children']/record">    
    <record>
        <xsl:apply-templates select=" @* | node()"/>
        <tuple name="top_record">
            <xsl:apply-templates select="ancestor::collection/record/atom[@name='irn']"/>
            <xsl:apply-templates select="ancestor::collection/record/atom[@name='EADUnitTitle']"/>
        </tuple>
    </record>    
</xsl:template>


</xsl:stylesheet>

我理想的是一个XSLT,它创建一个嵌套格式,并在其子代中包含父irn和title。

修改

道歉:原始的xml输入如下:

<table name="ecatalogue">
  <tuple>
    <atom name="irn">2470</atom>
    <atom name="EADUnitID"></atom>
    <atom name="EADUnitTitle"></atom>
    <atom name="EADLevelAttribute"></atom>
    <tuple name="AssParentObjectRef">
    </tuple>
  </tuple>

  <tuple>
    <atom name="irn">5416</atom>
    <atom name="EADUnitID"></atom>
    <atom name="EADUnitTitle"></atom>
    <tuple name="AssParentObjectRef">
      <atom name="irn">2470</atom>
      <atom name="EADUnitTitle"></atom>
    </tuple>
  </tuple>

  <tuple>
    <atom name="irn">7</atom>
    <atom name="EADUnitID"></atom>
    <atom name="EADUnitTitle"></atom>
    <tuple name="AssParentObjectRef">
      <atom name="irn">2470</atom>
      <atom name="EADUnitTitle"></atom>
    </tuple>
  </tuple>

  <tuple>
    <atom name="irn">8</atom>
    <atom name="ObjectType"></atom>
    <atom name="EADLevelAttribute"></atom>
    <atom name="EADUnitID"></atom>
    <atom name="EADUnitTitle"></atom>
    <tuple name="AssParentObjectRef">
      <atom name="EADUnitTitle"></atom>
      <atom name="irn">7</atom>
    </tuple>
  </tuple>
</table>

1 个答案:

答案 0 :(得分:1)

  

我需要在每个中都有顶级元素ID和标题的副本   孩子记录

将它们作为参数传递下去:

XSLT 1.0

<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:strip-space elements="*"/>

<xsl:key name="child" match="tuple" use="tuple[@name='AssParentObjectRef']/atom[@name='irn']" />

<xsl:template match="/table">
    <table name="ecatalogue">
        <collection>
            <xsl:apply-templates select="tuple[not(tuple[@name='AssParentObjectRef']/atom[@name='irn'])]"/>
        </collection>
    </table>
</xsl:template>

<xsl:template match="tuple">
    <xsl:param name="top-irn" select="atom[@name='irn']"/>
    <xsl:param name="top-title" select="atom[@name='EADUnitTitle']"/>
    <tuple>
        <xsl:copy-of select="atom"/>
        <atom name="Parent_irn">
            <xsl:value-of select="$top-irn"/>
        </atom>
        <atom name="Parent_title">
            <xsl:value-of select="$top-title"/>
        </atom>
        <xsl:if test="key('child', atom[@name='irn'])">
            <tuple name="children">
                <xsl:apply-templates select="key('child', atom[@name='irn'])">
                    <xsl:with-param name="top-irn" select="$top-irn"/>
                    <xsl:with-param name="top-title" select="$top-title"/>
                </xsl:apply-templates>
             </tuple>
        </xsl:if>
    </tuple>
</xsl:template>

</xsl:stylesheet>