XSLT基于子数据的子进行拆分

时间:2011-03-09 02:13:16

标签: xslt split messages xslt-1.0

我有:

<?xml version="1.0" encoding="utf-8"?>
<parent>
 <parentspecialinfo>blond</parentspecialinfo>
  <child>
    <grandchild>
      <grandchildtype>special</grandchildtype>
      <specialvalue>123</specialvalue>
      <otherstuff>123</otherstuff>
      <otherstuff2>abc</otherstuff2>
      <otherstuff3>zxc</otherstuff3>
    </grandchild>
    <grandchild>
      <grandchildtype>red</grandchildtype>
      <specialvalue>345</specialvalue>
      <otherstuff>123</otherstuff>
      <otherstuff2>abc</otherstuff2>
      <otherstuff3>zxc</otherstuff3>
    </grandchild>
    <grandchild>
      <grandchildtype>blue</grandchildtype>
      <specialvalue>678</specialvalue>
      <otherstuff>123</otherstuff>
      <otherstuff2>abc</otherstuff2>
      <otherstuff3>zxc</otherstuff3>
    </grandchild>
    <otherchildthings>tiger</otherchildthings>
  </child>
  <child>
    <grandchild>
      <grandchildtype>special</grandchildtype>
      <specialvalue>123</specialvalue>
      <otherstuff>123</otherstuff>
      <otherstuff2>abc</otherstuff2>
      <otherstuff3>zxc</otherstuff3>
    </grandchild>
    <otherchildthings>tiger</otherchildthings>
  </child>
  <child>
    <grandchild>
      <grandchildtype>red</grandchildtype>
      <specialvalue>345</specialvalue>
      <otherstuff>123</otherstuff>
      <otherstuff2>abc</otherstuff2>
      <otherstuff3>zxc</otherstuff3>
    </grandchild>
    <grandchild>
      <grandchildtype>blue</grandchildtype>
      <specialvalue>678</specialvalue>
      <otherstuff>123</otherstuff>
      <otherstuff2>abc</otherstuff2>
      <otherstuff3>zxc</otherstuff3>
    </grandchild>
    <grandchild>
      <grandchildtype>special</grandchildtype>
      <specialvalue>999</specialvalue>
      <otherstuff>123</otherstuff>
      <otherstuff2>abc</otherstuff2>
      <otherstuff3>zxc</otherstuff3>
    </grandchild>
    <otherchildthings>tiger</otherchildthings>
  </child>
</parent>

我需要将整个子记录集复制到一个新的父元素中,保留grandchildtype特殊的每个唯一特殊值集的所有父节点信息。因此,对于这个例子,我们只有2,123和999.但是可能有许多组唯一值。我在移动链条以保留所有元素方面遇到了一些麻烦。我正在尝试使用xsl:key元素,但还没有走得太远。这是解决这个问题的好方法吗?

所以这就是结果:

<?xml version="1.0" encoding="utf-8"?>
<parent>
  <parentspecialinfo>blond</parentspecialinfo>
  <child>
    <grandchild>
      <grandchildtype>special</grandchildtype>
      <specialvalue>123</specialvalue>
      <otherstuff>123</otherstuff>
      <otherstuff2>abc</otherstuff2>
      <otherstuff3>zxc</otherstuff3>
    </grandchild>
    <grandchild>
      <grandchildtype>red</grandchildtype>
      <specialvalue>345</specialvalue>
      <otherstuff>123</otherstuff>
      <otherstuff2>abc</otherstuff2>
      <otherstuff3>zxc</otherstuff3>
    </grandchild>
    <grandchild>
      <grandchildtype>blue</grandchildtype>
      <specialvalue>678</specialvalue>
      <otherstuff>123</otherstuff>
      <otherstuff2>abc</otherstuff2>
      <otherstuff3>zxc</otherstuff3>
    </grandchild>
    <otherchildthings>tiger</otherchildthings>
  </child>
  <child>
    <grandchild>
      <grandchildtype>special</grandchildtype>
      <specialvalue>123</specialvalue>
      <otherstuff>123</otherstuff>
      <otherstuff2>abc</otherstuff2>
      <otherstuff3>zxc</otherstuff3>
    </grandchild>
    <otherchildthings>tiger</otherchildthings>
  </child>
</parent>
<parent>
  <parentspecialinfo>blond</parentspecialinfo>
  <child>
    <grandchild>
      <grandchildtype>red</grandchildtype>
      <specialvalue>345</specialvalue>
      <otherstuff>123</otherstuff>
      <otherstuff2>abc</otherstuff2>
      <otherstuff3>zxc</otherstuff3>
    </grandchild>
    <grandchild>
      <grandchildtype>blue</grandchildtype>
      <specialvalue>678</specialvalue>
      <otherstuff>123</otherstuff>
      <otherstuff2>abc</otherstuff2>
      <otherstuff3>zxc</otherstuff3>
    </grandchild>
    <grandchild>
      <grandchildtype>special</grandchildtype>
      <specialvalue>999</specialvalue>
      <otherstuff>123</otherstuff>
      <otherstuff2>abc</otherstuff2>
      <otherstuff3>zxc</otherstuff3>
    </grandchild>
    <otherchildthings>tiger</otherchildthings>
  </child>
</parent>

我已经被要求澄清这里是我的psuedo代码从我的LINQ解决方案中走过来。我希望它有所帮助: 1)通过复制<parent>创建shell节点集。 2)从shell节点中删除所有<child>个元素。 3)查询所有<child>个节点的原始文档。 4)对于每个<child>节点,找到<specialvalue>&gt; <grandchildtype的值<specialvalue>价值是“特殊的” 5)检查我们是否已经看到<child>如果没有,那么将整个<child>添加到集合中。如果我们已经看过它,那么在集合中找到它并将其添加到该位置的集合中。 6)对于每个集合值,将{{1}}个节点添加到在步骤1中创建的新shell节点。 7)将上面创建的所有节点添加到同一文档中。

谢谢。

1 个答案:

答案 0 :(得分:0)

更新:使用新的输入源,此样式表(覆盖身份规则):

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:key name="kChildBySpecialvalue"
             match="child"
             use="concat(
                     generate-id(..),'+',
                     grandchild[grandchildtype='special']/specialvalue
                  )"/>
    <xsl:template match="node()|@*">
        <xsl:copy>
            <xsl:apply-templates select="node()|@*"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="parent">
        <xsl:variable name="vCurrent" select="."/>
        <xsl:for-each select="child[
                                 count(.|key('kChildBySpecialvalue',
                                             concat(
                                                generate-id($vCurrent),'+',
                                                grandchild[
                                                   grandchildtype = 'special'
                                                ]/specialvalue
                                             )
                                         )[1]
                                 ) = 1
                              ]">
            <xsl:variable name="vGroup"
                          select="key('kChildBySpecialvalue',
                                      concat(
                                         generate-id($vCurrent),'+',
                                         grandchild[
                                            grandchildtype = 'special'
                                         ]/specialvalue
                                      )
                                  )"/>
            <xsl:for-each select="$vCurrent">
                <xsl:copy>
                    <xsl:apply-templates
                         select="node()[not(self::child)]|$vGroup|@*"/>
                </xsl:copy>
            </xsl:for-each>
        </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>

输出:

<parent>
    <parentspecialinfo>blond</parentspecialinfo>
    <child>
        <grandchild>
            <grandchildtype>special</grandchildtype>
            <specialvalue>123</specialvalue>
            <otherstuff>123</otherstuff>
            <otherstuff2>abc</otherstuff2>
            <otherstuff3>zxc</otherstuff3>
        </grandchild>
        <grandchild>
            <grandchildtype>red</grandchildtype>
            <specialvalue>345</specialvalue>
            <otherstuff>123</otherstuff>
            <otherstuff2>abc</otherstuff2>
            <otherstuff3>zxc</otherstuff3>
        </grandchild>
        <grandchild>
            <grandchildtype>blue</grandchildtype>
            <specialvalue>678</specialvalue>
            <otherstuff>123</otherstuff>
            <otherstuff2>abc</otherstuff2>
            <otherstuff3>zxc</otherstuff3>
        </grandchild>
        <otherchildthings>tiger</otherchildthings>
    </child>
    <child>
        <grandchild>
            <grandchildtype>special</grandchildtype>
            <specialvalue>123</specialvalue>
            <otherstuff>123</otherstuff>
            <otherstuff2>abc</otherstuff2>
            <otherstuff3>zxc</otherstuff3>
        </grandchild>
        <otherchildthings>tiger</otherchildthings>
    </child>
</parent>
<parent>
    <parentspecialinfo>blond</parentspecialinfo>
    <child>
        <grandchild>
            <grandchildtype>red</grandchildtype>
            <specialvalue>345</specialvalue>
            <otherstuff>123</otherstuff>
            <otherstuff2>abc</otherstuff2>
            <otherstuff3>zxc</otherstuff3>
        </grandchild>
        <grandchild>
            <grandchildtype>blue</grandchildtype>
            <specialvalue>678</specialvalue>
            <otherstuff>123</otherstuff>
            <otherstuff2>abc</otherstuff2>
            <otherstuff3>zxc</otherstuff3>
        </grandchild>
        <grandchild>
            <grandchildtype>special</grandchildtype>
            <specialvalue>999</specialvalue>
            <otherstuff>123</otherstuff>
            <otherstuff2>abc</otherstuff2>
            <otherstuff3>zxc</otherstuff3>
        </grandchild>
        <otherchildthings>tiger</otherchildthings>
    </child>
</parent>

注意:当parent等于child时,specialvalue grandchildtype个孩子在'special'之后;为每个群体复制自己,其他孩子和群体。