【问题标题】:merging and restructing nodes content based on attribute values基于属性值合并和重组节点内容
【发布时间】:2011-11-01 20:21:26
【问题描述】:

我有一个包含以下标记的 xml 文件

 <xml>
   <content relationship="regula">
       **<source attribute1="RSC1985s5c1" attribute2="6(17)"/>**
       <target attribute1="LRC1985s5c1" attribute1="6(17)1"/>
   </content>

   <content relationship="translation-of">
       **<source attribute1="RSC1985s5c1" attribute2="6(17)"/>**
       <target attribute1="LRC1985s5c4" attribute2="6(17)1"/>
   </content>

   <content relationship="translation-of">
       **<source attribute1="RSC1985s5c2" attribute2="7(17)"/>**
       <target attribute1="LRC1985s5c2" attribute2="7(17)"/>
    </content>

     <content relationship="translation-of">
         **<source attribute1="RSC1985s5c1" attribute2="6(17)"/>**
           <target attribute1="LRC1985s5c6" attribute2="6(17)2"/>
     </content>

   </xml>

如果源节点的属性 1 和属性 2 值相等,我想要将节点的内容合并到一个新节点中。所以输出应该是这样的

   <xml>
    <transformed relationship="merged">
          <source attribute1="RSC1985s5c1" attribute2="6(17)"/>
          <target attribute1="LRC1985s5c1" attribute2="6(17)1"/>
          <target attribute1="LRC1985s5c4" attribute2="6(17)1"/>
          <target attribute1="LRC1985s5c6" attribute2="6(17)2"/>
    </transformed>

      <transformed relationship="non-merged">
          <source attribute1="RSC1985s5c2" attribute2="7(17)"/>
           <target attribute1="LRC1985s5c2" attribute2="7(17)"/>
    </transformed>
   </xml>

所以前两个节点的源属性 1 和属性 2 值彼此相等,这就是我将它们组合为一个新节点的原因。源中的第三个节点与其他节点不匹配,这就是我单独输出的原因。我尝试使用 foreach 循环,但无法正确解决。如果我们可以通过模板匹配实现,感谢您的帮助。

任何具有相同子节点“源”属性的内容节点都应该组合在一起,无论它们的位置如何。对于合并的项目,关系将更改为“合并”,未合并的项目将是“未合并”

【问题讨论】:

  • @_atif: 是否应该合并任何两个具有“共同”子节点的content 节点?是否只合并两个相邻的content 节点?如果两个以上的content 节点有“共同”元素怎么办? relation 属性真的应该因为合并而丢失吗?这个问题有太多不清楚的地方。请编辑并提供缺失的信息。
  • 任何具有相同子节点“源”属性的内容节点都应该组合在一起,无论它们的位置如何。对于合并的项目,关系将更改为“合并”,未合并的项目将是“未合并”
  • @_atif:嗯,这很好在评论中说,但它属于问题 - 请编辑您的问题并在那里提供此信息。另外,您没有回答我的问题,合并两个以上节点的预期输出 id 应该是什么——请在您的问题中提供这样的示例。我绝对不愿意去猜测你可能没有想过的事情......

标签: xslt


【解决方案1】:

这可以通过 Muenchian Grouping 来实现

因为您需要在 source 元素上匹配两个单独的属性,所以您可能需要使用连接键,像这样

<xsl:key name="dupes" 
  match="content/source" 
  use="concat(@attribute1, '|', @attribute2)" />

选择一个连接字符来分隔永远不会出现在两个属性值中的两个属性(在本例中为管道)很重要。

通常,要匹配每个组中的第一个元素,您可以这样做

<xsl:apply-templates select="content/source
   [generate-id() = 
    generate-id(key('dupes', concat(@attribute1, '|', @attribute2))[1])]" />

但是,您需要做一些额外的工作,因为您需要知道哪些 source 元素在组中有多个项目,哪些只包含单个项目。因此,要获取包含多个项目的组,您可以执行以下操作:

<xsl:apply-templates select="content/source
   [generate-id() = 
      generate-id(key('dupes', concat(@attribute1, '|', @attribute2))[1])]
      [count(key('dupes', concat(@attribute1, '|', @attribute2))) > 1]" />

这是完整的 XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:key name="dupes" match="content/source" use="concat(@attribute1, '|', @attribute2)"/>

   <xsl:template match="/xml">
      <xsl:copy>
         <transformed relationship="merged">
            <xsl:apply-templates select="content/source[generate-id() = generate-id(key('dupes', concat(@attribute1, '|', @attribute2))[1])][count(key('dupes', concat(@attribute1, '|', @attribute2))) &gt; 1]"/>
         </transformed>
         <transformed relationship="non-merged">
            <xsl:apply-templates select="content/source[generate-id() = generate-id(key('dupes', concat(@attribute1, '|', @attribute2))[1])][count(key('dupes', concat(@attribute1, '|', @attribute2))) = 1]"/>
         </transformed>
      </xsl:copy>
   </xsl:template>

   <xsl:template match="source">
      <xsl:copy-of select="."/>
      <xsl:copy-of select="key('dupes', concat(@attribute1, '|', @attribute2))/following-sibling::target[1]"/>
   </xsl:template>
</xsl:stylesheet>

当应用于您的示例 XML 时,将输出以下内容

<xml>
   <transformed relationship="merged">
      <source attribute1="RSC1985s5c1" attribute2="6(17)"/>
      <target attribute1="LRC1985s5c1" attribute2="6(17)1"/>
      <target attribute1="LRC1985s5c4" attribute2="6(17)1"/>
      <target attribute1="LRC1985s5c6" attribute2="6(17)2"/>
   </transformed>
   <transformed relationship="non-merged">
      <source attribute1="RSC1985s5c2" attribute2="7(17)"/>
      <target attribute1="LRC1985s5c2" attribute2="7(17)"/>
   </transformed>
</xml>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-06-11
    • 2021-05-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多