繁体   English   中英

XSLT从子节点创建父节点的副本

[英]XSLT Create copies of Parent Node from Child Nodes

我正在使用XSLT,并且有一个我不确定如何继续的要求。

由于场景很难解释,因此我在下面提供了图像。

之前 :有1个树节点,每个节点中有2个叶节点。

之后 :有2个树节点。 第一棵树在叶子下保存第一个叶子节点,第二棵树在叶子下保存第二个叶子节点。

在XML映像之前

XML图像之后

我不确定是否应该在模板匹配中从树->叶子向内走,或从树->树向内走。

感谢您的任何帮助!

更新:

在XML作为文本之前

<?xml version="1.0" encoding="UTF-8"?>
<tree uId="0">
  <branches uId="1">
    <branch uId="2">
      <branchId uId="3">0988890098887656</branchId>
      <number uId="4">7</number>
      <leaves uId="5">
        <leaf uId="6">
          <name uId="7">Leaf 1</name>
        </leaf>
        <leaf uId="8">
          <name uId="9">Leaf 2</name>
        </leaf>
      </leaves>
      <bugs uId="10">10</bugs>
    </branch>
    <branch uId="11">
      <branchId uId="12">66677755564446</branchId>
      <number uId="13" />
      <leaves uId="14">
        <leaf uId="15">
          <name uId="16">Leaf 1</name>
        </leaf>
        <leaf uId="17">
          <name uId="18">Leaf 2</name>
        </leaf>
      </leaves>
      <bugs uId="19" />
    </branch>
  </branches>
  <title uId="20">Great Tree</title>
</tree>

在XML作为文本之后:

<tree uId="0">
  <branches uId="1">
    <branch uId="2">
      <branchId uId="3">0988890098887656</branchId>
      <number uId="4">7</number>
      <leaves uId="5">
        <leaf uId="6">
          <name uId="7">Leaf 1</name>
        </leaf>
      </leaves>
      <bugs uId="10">10</bugs>
    </branch>
    <branch uId="11">
      <branchId uId="12">66677755564446</branchId>
      <number uId="13" />
      <leaves uId="14">
        <leaf uId="15">
          <name uId="16">Leaf 1</name>
        </leaf>
      </leaves>
      <bugs uId="19" />
    </branch>
  </branches>
  <title uId="20">Great Tree</title>
</tree>
<tree>
  <branches>
    <branch>
      <branchId>0988890098887656</branchId>
      <number>7</number>
      <leaves>
        <leaf uId="8">
          <name uId="9">Leaf 2</name>
        </leaf>
      </leaves>
      <bugs>10</bugs>
    </branch>
    <branch>
      <branchId>66677755564446</branchId>
      <number/>
      <leaves>
        <leaf uId="17">
          <name uId="18">Leaf 2</name>
        </leaf>
      </leaves>
      <bugs />
    </branch>
  </branches>
  <title>Great Tree</title>
</tree>

XSLT:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:exsl="http://exslt.org/common"
    exclude-result-prefixes="xs"
    version="1.0">

    <xsl:template match="tree">
        <xsl:variable name="copies">
            <xsl:call-template name="getTreeCopies" />
        </xsl:variable>

        <xsl:copy-of select="exsl:node-set($copies)/*"/>

    </xsl:template>

    <xsl:template name="getTreeCopies">
        <xsl:variable name="countOfLeaf" select="count((.//leaves)[1]/leaf)" />
        <xsl:call-template name="getTreeCopy">
            <xsl:with-param name="i">1</xsl:with-param>
            <xsl:with-param name="count">
                <xsl:value-of select="$countOfLeaf" />
            </xsl:with-param>
        </xsl:call-template>
    </xsl:template>

    <xsl:template name="getTreeCopy">
        <xsl:param name="i" />
        <xsl:param name="count" />

        <xsl:if test="$i &lt;= $count">
            <xsl:copy-of select="."/>
            <xsl:call-template name="getTreeCopy" >
                <xsl:with-param name="i">
                    <xsl:value-of select="$i + 1"/>
                </xsl:with-param>
                <xsl:with-param name="count">
                    <xsl:value-of select="$count"/>
                </xsl:with-param>
            </xsl:call-template>
        </xsl:if>
    </xsl:template>
</xsl:stylesheet>

到目前为止,我的XSLT复制树节点(每个分支的叶子节点中的叶子节点数)倍。 下一步是从树1删除位置1的叶子,从树2删除位置2的叶子...等等,然后从原始树的任何副本中删除uid属性。

另一种方法是:

  • 根据leaf的位置创建一个键。
  • 处理每个密钥的第一leaf Muenchian分组
  • 键中的第一个叶子触发对祖先树(及其后代)的处理。
  • 密钥中所有leaf的生成ID的列表作为参数传递。 (由于XSLT 1.0不支持隧道,因此需要在每个apply-templates调用中传递它。)
  • 处理leaves元素时,仅处理具有匹配的生成ID的leaf元素。
  • 使用mode可以控制是否处理属性。

示例(也在此处演示: http : //xsltfiddle.liberty-development.net/6qM2e2a )...

XML输入

<tree uId="0">
    <branches uId="1">
        <branch uId="2">
            <branchId uId="3">0988890098887656</branchId>
            <number uId="4">7</number>
            <leaves uId="5">
                <leaf uId="6">
                    <name uId="7">Leaf 1</name>
                </leaf>
                <leaf uId="8">
                    <name uId="9">Leaf 2</name>
                </leaf>
            </leaves>
            <bugs uId="10">10</bugs>
        </branch>
        <branch uId="11">
            <branchId uId="12">66677755564446</branchId>
            <number uId="13" />
            <leaves uId="14">
                <leaf uId="15">
                    <name uId="16">Leaf 1</name>
                </leaf>
                <leaf uId="17">
                    <name uId="18">Leaf 2</name>
                </leaf>
            </leaves>
            <bugs uId="19" />
        </branch>
    </branches>
    <title uId="20">Great Tree</title>
</tree>

XSLT 1.0

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output indent="yes"/>
  <xsl:strip-space elements="*"/>

  <xsl:key name="leaves" match="leaf" use="count(preceding-sibling::leaf) + 1"/>

  <xsl:template match="/">
    <xsl:apply-templates select="//leaf[count(.|key('leaves',count(preceding-sibling::leaf) + 1)[1])=1]"/>
  </xsl:template>

  <xsl:template match="@*|node()" mode="full">
    <xsl:param name="leafId"/>
    <xsl:copy>
      <xsl:apply-templates select="@*|node()" mode="full">
        <xsl:with-param name="leafId" select="$leafId"/>
      </xsl:apply-templates>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="@*|node()" mode="partial">
    <xsl:param name="leafId"/>
    <xsl:copy>
      <xsl:apply-templates select="node()" mode="partial">
        <xsl:with-param name="leafId" select="$leafId"/>
      </xsl:apply-templates>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="leaves" mode="full">
    <xsl:param name="leafId"/>
    <xsl:copy>
      <xsl:apply-templates select="@*|leaf[contains($leafId,concat('|',generate-id()))]" mode="full"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="leaves" mode="partial">
    <xsl:param name="leafId"/>
    <xsl:copy>
      <xsl:apply-templates select="leaf[contains($leafId,concat('|',generate-id()))]" mode="full"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="leaf">
    <xsl:variable name="leafId">
      <xsl:for-each select="key('leaves',count(preceding-sibling::leaf)+1)">
        <xsl:value-of select="concat('|',generate-id())"/>
      </xsl:for-each>
    </xsl:variable>
    <xsl:choose>
      <xsl:when test="position() = 1">
        <xsl:apply-templates select="ancestor::tree" mode="full">
          <xsl:with-param name="leafId" select="$leafId"/>
        </xsl:apply-templates>
      </xsl:when>
      <xsl:otherwise>
        <xsl:apply-templates select="ancestor::tree" mode="partial">
          <xsl:with-param name="leafId" select="$leafId"/>
        </xsl:apply-templates>        
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>

</xsl:stylesheet>

输出量

<tree uId="0">
   <branches uId="1">
      <branch uId="2">
         <branchId uId="3">0988890098887656</branchId>
         <number uId="4">7</number>
         <leaves uId="5">
            <leaf uId="6">
               <name uId="7">Leaf 1</name>
            </leaf>
         </leaves>
         <bugs uId="10">10</bugs>
      </branch>
      <branch uId="11">
         <branchId uId="12">66677755564446</branchId>
         <number uId="13"/>
         <leaves uId="14">
            <leaf uId="15">
               <name uId="16">Leaf 1</name>
            </leaf>
         </leaves>
         <bugs uId="19"/>
      </branch>
   </branches>
   <title uId="20">Great Tree</title>
</tree>
<tree>
   <branches>
      <branch>
         <branchId>0988890098887656</branchId>
         <number>7</number>
         <leaves>
            <leaf uId="8">
               <name uId="9">Leaf 2</name>
            </leaf>
         </leaves>
         <bugs>10</bugs>
      </branch>
      <branch>
         <branchId>66677755564446</branchId>
         <number/>
         <leaves>
            <leaf uId="17">
               <name uId="18">Leaf 2</name>
            </leaf>
         </leaves>
         <bugs/>
      </branch>
   </branches>
   <title>Great Tree</title>
</tree>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM