【问题标题】:Group/merge childs of same nodes in xml/xslt when repeating upper nodes重复上层节点时,在 xml/xslt 中对相同节点的子节点进行分组/合并
【发布时间】:2012-08-15 13:43:33
【问题描述】:

作为对我的原始帖子Group/merge childs of same nodes in xml/xslt 的补充,我遇到了让该结构针对不同节点(层次结构中较高的节点)重复多次的问题,例如,

<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 上匹配,因为后者并不总是存在)?注意:相同的GroupData节点(具有相应的属性)必须在每个FormData节点中合并为一个GroupData节点。

【问题讨论】:

  • @SeanB.Durkin - 问题是,“那么我怎样才能让每个 GroupData 节点的子节点进入一个 GroupData 节点(匹配 ID,有时匹配 Key,因为后者并不总是存在)? "
  • Mat90,人们需要了解什么是想要的结果以及转换的规则是什么。请编辑问题并提供此缺失信息。另外,请不要在提供的 XML 文档中使用省略号——这可能会非常混乱。
  • 即使看了你之前的问题,我也花了一段时间才明白你想要什么。您希望通过 ID、Key 和 FormData 的乘积合并 GroupData 节点。也就是说GroupData由ID和Key合并而成,个FormData元素。

标签: xslt nodes


【解决方案1】:

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

一种解决方案是从您的第一个问题中获取 Dimite 的解决方案,然后将密钥扩展为包含 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 ...

<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 都会被删除。

【讨论】:

    猜你喜欢
    • 2012-08-07
    • 2015-05-15
    • 2021-03-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多