将元素分组到新父节点(XSLT)

时间:2014-02-10 18:13:36

标签: xml xslt xpath transform

我是初学者学习xsl,我需要帮助xsl文件来转换我的原始xml,看起来像

<dataroot>
    <pod>
      <id>1</id>
      <mfp>
        <type>1</type>
        <val>10</val>
      </mfp>
      <mfp>
        <type>2</type>
        <val>12</val>
      </mfp>
    </pod>
    <pod>
      <id>2</id>
      <mfp>
        <type>1</type>
        <val>100</val>
      </mfp>
    </pod>
</dataroot>

我需要有一个新的节点MFPS,它包含一个pod的所有mfp元素,比如

<dataroot>
    <pod>
      <id>1</id>
      <MFPS>
        <mfp>
          <type>1</type>
          <val>10</val>
        </mfp>
        <mfp>
          <type>2</type>
          <val>12</val>
        </mfp>
      </MFPS>
    </pod>
    <pod>
      <id>2</id>
      <MFPS>
        <mfp>
          <type>1</type>
          <val>100</val>
        </mfp>
      </MFPS>
    </pod>
</dataroot>

请帮我解决这个问题。感谢

2 个答案:

答案 0 :(得分:0)

使用此模板:

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

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

  <xsl:template match="pod">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()[not(name() = 'mfp')]"/>
      <MFPS>
        <xsl:apply-templates select="mfp"/>
      </MFPS>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

答案 1 :(得分:0)

使用XSLT 2.0,您可以使用for-each-group

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

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

    <xsl:template match="pod">
        <xsl:copy>
            <xsl:for-each-group select="*" group-adjacent="if (self::mfp) then 1 else 0">
                <xsl:choose>
                    <xsl:when test="current-grouping-key()">
                        <MFPS>
                            <xsl:apply-templates select="current-group()"/>
                        </MFPS>
                    </xsl:when>
                    <xsl:otherwise>
                        <xsl:apply-templates select="current-group()"/>
                    </xsl:otherwise>
                </xsl:choose>
            </xsl:for-each-group>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>