【问题标题】:merging multiple attribute nodes with same value合并具有相同值的多个属性节点
【发布时间】:2019-06-11 10:13:10
【问题描述】:

能否请您帮我了解如何执行此 xml: xml 看起来像

    <a name="hr_1" id="hr">
    <text>11</text>
    </a>
    <a name="hr_2" id="hr">
    <text>12</text>
    </a>

    <a name="hre_1" id ="hre">
    <text>11</text>
    </a>
    <a name="hre_2" id ="hre">
    <text>12</text>
    </a>

预期输出:转换后的输出预期如下所示

    <b name ="hr">
    <value>11</value>
    <value>12</value>
    </b>

    <b name ="hre">
    <value>11</value>
    <value>12</value>
    </b>

【问题讨论】:

  • 你能解释合并那些a 元素或它们的text 子元素的规则吗?这是基于text 的值吗?另外,您使用/可以使用哪个 XSLT 版本?
  • 它是基于名称的,因此 hr_1,hr_2 .. 等的所有值都需要组合...同样 hre_1,hre_2.. 等的所有值都需要组合。 xslt 1.2
  • 您能解释一下name 属性的预期结构吗?您想按substring-before(@name, '_') 分组吗?但是,在您的预期输出中,hre_x 元素的合并值在哪里?
  • 是的,完全正确
  • 那么您的预期输出是否正确,因为它缺少名称“hre”的条目。谢谢!

标签: xml xslt xslt-1.0


【解决方案1】:

看起来像一个简单的分组任务,可以在 XSLT 2 或 3 中用xsl:for-each-group 解决:

  <xsl:template match="root">
      <xsl:copy>
          <xsl:for-each-group select="a" group-by="substring-before(@name, '_')">
              <b name="{current-grouping-key()}">
                  <xsl:copy-of select="current-group()/*"/>
              </b>
          </xsl:for-each-group>
      </xsl:copy>
  </xsl:template>

假设 root 是要分组的 a 元素的公共容器元素,根据需要进行调整。

【讨论】:

  • 非常感谢...我如何在 xslt 1.0 中做到这一点。我还添加了一个标签 id,所以我需要根据 id 进行分组。请在 xslt 1.0 中提供帮助
【解决方案2】:

来自评论:

非常感谢...我如何在 xslt 1.0 中做到这一点。我还添加了一个 更多标签 id,所以我需要根据 id 进行分组。请在 xslt 1.0 中提供帮助

在 XSLT 1.0 中,使用 Muenchian Grouping。我要做的是创建一个匹配所有text 元素并使用父级的id 属性的键...

XML

<doc>
    <a name="hr_1" id="hr">
        <text>11</text>
    </a>
    <a name="hr_2" id="hr">
        <text>12</text>
    </a>    
    <a name="hre_1" id ="hre">
        <text>11b</text>
    </a>
    <a name="hre_2" id ="hre">
        <text>12b</text>
    </a>
</doc>

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="kText" match="text" use="../@id"/>

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

  <xsl:template match="/*">
    <xsl:copy>
      <xsl:apply-templates select="@*"/>
      <xsl:for-each select="*/text[count(.|key('kText',../@id)[1])=1]">
        <b name="{../@id}">
          <xsl:apply-templates select="key('kText',../@id)"/>
        </b>
      </xsl:for-each>
    </xsl:copy>
  </xsl:template>

</xsl:stylesheet>

输出

<doc>
   <b name="hr">
      <text>11</text>
      <text>12</text>
   </b>
   <b name="hre">
      <text>11b</text>
      <text>12b</text>
   </b>
</doc>

【讨论】:

  • 谢谢..你能帮忙解释一下两个文本节点是如何被复制到同一个 b 标记内的吗......我不明白 复制了 b 标签内的两个文本节点
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-29
  • 1970-01-01
  • 2021-07-09
  • 1970-01-01
相关资源
最近更新 更多