重复上层节点时,在 xml/xslt 中对相同节点的子节点进行分组/合并 [英] Group/merge childs of same nodes in xml/xslt when repeating upper nodes

查看:89
本文介绍了重复上层节点时,在 xml/xslt 中对相同节点的子节点进行分组/合并的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

作为我原始帖子的补充 分组/合并孩子xml/xslt 中相同节点的问题 我遇到了为不同的节点重复多次该结构的问题(在层次结构中的节点较高),例如,

As an addition to my orginal post Group/merge childs of same nodes in xml/xslt I ran into the problem of having that structure repeated multiple times for different nodes (wihtin nodes higher in the hierarchy) e.g.,

<Collection>
    <Questionnaire Name="Preferences" VersionID="3QW">
        <Subject ID="2355">
            <EventData Name="First Part">
                <FormData Name="Past">
                    <GroupData ID="xxx" Key="4" Temp="yyy">
                        <ItemData ID="zzz" Value="3"/>
                    </GroupData>
                    <GroupData ID="xxx" Key="4" Temp="yyy">
                        <ItemData ID="qqq" Value="4"/>
                    </GroupData>
                    ...
                </FormData>
                <FormData Name="Present">
                    <GroupData ID="yyy" Key="9" Temp="yyy">
                        <ItemData ID="www" Value="32"/>
                    </GroupData>
                    ...
                </FormData>             
            </EventData>
            <EventData Name="SecondPart">
                ...
            </EventData>
        </Subject>
        <Subject ID="9812">
            ...
        </Subject>
    </Questionnaire>    
</Collection>   

在尝试对我重新获得的建议和其他一些事情进行修改后,我陷入了困境.我认为它与多个级别有关(并且 GroupData 分布在它将成为子节点的上层/祖父节点上),然后它可能不再具有唯一 ID.那么如何将每个 GroupData 节点的子节点放入一个 GroupData 节点(匹配 ID,有时匹配 Key,因为后者并不总是存在)?注意:每个FormData节点中必须将相同的GroupData节点(具有对应的属性)合并为一个GroupData节点.

After trying variations on the suggestions I reveived and some other things I am stuck. I think it has something to do with multiple levels (and GroupData being spread over upper/grandparent nodes in which it will be a child) and then it possiblly does not have unique IDs anymore. So how can I get the childs of each GroupData node into one GroupData node (matched on ID and sometimes Key, since the latter is not always present)? Note: The same GroupData nodes (with corresponding attributes) must be merged into one GroupData node in each FormData node.

推荐答案

这里有两个 XSLT 1.0 解决方案.

Here are two XSLT 1.0 solutions.

一个解决方案是从您的第一个问题中获取 Dimite 的解决方案,然后将键扩展为包含 FormData...

One solution is to take Dimite's solution from your first question, and just expand the key to include FormData...

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

 <xsl:key name="kGDByIdKey" match="FormData/GroupData"
  use="concat(@ID, '+', @Key, '+', generate-id(..))"/>

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

 <xsl:template match=
 "FormData/GroupData
    [generate-id()
    =
     generate-id(key('kGDByIdKey', concat(@ID, '+', @Key, '+', generate-id(..)))[1])
     ]">
    <xsl:copy>
      <xsl:apply-templates select=
       "@*|key('kGDByIdKey', concat(@ID, '+', @Key, '+', generate-id(..)))/node()"/>
    </xsl:copy>
 </xsl:template>

  <xsl:template match="GroupData"/>
</xsl:stylesheet>

另一种解决方案将分组测试从模板匹配条件移动到父 FormData 中调用 xsl:apply-templates ...

Another solution moves the grouping test from the template match condition to the the invoking xsl:apply-templates in the parent FormData ...

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

 <xsl:key name="kGDByIdKey" match="FormData/GroupData" use="concat(@ID, '+', @Key)" />

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

 <xsl:template match="FormData">
     <xsl:copy>
       <xsl:apply-templates select="
          @* |
          node()[not(self::GroupData)] |
          GroupData[generate-id() =
                    generate-id(key('kGDByIdKey', concat(@ID, '+', @Key))[1])]"/>
     </xsl:copy>
 </xsl:template>

 <xsl:template match="FormData/GroupData">
     <xsl:copy>
       <xsl:apply-templates select="@*|
           key('kGDByIdKey', concat(@ID, '+', @Key))/node()"/>
     </xsl:copy>
 </xsl:template>
  <xsl:template match="GroupData"/>
</xsl:stylesheet>

两个样式表都假定 GroupData 的父级永远只是 FormData.删除任何没有 FormData 父级的 GroupData.

Both stylesheets assume that GroupData's parent is only ever FormData. Any GroupData which does not have a FormData parent is removed.

这篇关于重复上层节点时,在 xml/xslt 中对相同节点的子节点进行分组/合并的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆