merging multiple attribute nodes with same value

2019-08-18 08:01发布

Can you please help me on how to do this xml: The xml looks like

    <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>

expected output:The transformed output is expected like below

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

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

2条回答
够拽才男人
2楼-- · 2019-08-18 08:39

Seems like a simple grouping task then, solvable in XSLT 2 or 3 with 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>

Assumes root is the common container element for the a elements to be grouped, adapt that as needed.

查看更多
唯我独甜
3楼-- · 2019-08-18 08:57

From comment:

Thank you so much... How can i do it in xslt 1.0.. Also i added one more tag id, so i need to group based on id.Please help in xslt 1.0

In XSLT 1.0, use Muenchian Grouping. What I would do is create a key matching all text elements and using the id attribute of the parent...

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>

Output

<doc>
   <b name="hr">
      <text>11</text>
      <text>12</text>
   </b>
   <b name="hre">
      <text>11b</text>
      <text>12b</text>
   </b>
</doc>
查看更多
登录 后发表回答