将相同节点分组为单个父节点

时间:2012-12-11 05:48:42

标签: xslt-1.0 xslt-2.0

我有如下的XML内容:

<details>
      <name>Name 1</name>
      <name>Name 2</name>
      <name>Name 3</name>
      <address>Address 1</address>
      <address>Address 2</address>
      <address>Address 3</address>
      <address>Address 4</address>
  ....
</details>

我想获得如下输出:

<details>
 <names>      
      <name>Name 1</name>
      <name>Name 2</name>
      <name>Name 3</name>
 </names>
 <addresses>
     <address>Address 1</address>
     <address>Address 2</address>
     <address>Address 3</address>
     <address>Address 4</address>
 </addresses>

...     

我尝试使用以下XSL,但我没有得到所需的输出:

 <xsl:template match="address">
    <addresses>
        <xsl:for-each select="*">
            <xsl:apply-templates/>
        </xsl:for-each>
    </addresses>
</xsl:template>

1 个答案:

答案 0 :(得分:0)

您知道details元素的子元素的名称和数量吗?在这种情况下,使用

就足够了
<xsl:template match="details">
  <xsl:copy>
   <names>
     <xsl:copy-of select="name"/>
   </names>
   <addresses>
     <xsl:copy-of select="address"/>
   </addresses>
 </xsl:copy>
</xsl:template>

<xsl:output indent="yes"/>

如果您不知道子元素的名称和数量,您可以按名称分组,尽管然后生成包装元素名称的复数可能很困难(即名称 - >名称,但地址 - >地址):

<xsl:template match="details">
  <xsl:copy>
    <xsl:for-each-group select="*" group-by="local-name(.)">
     <xsl:element name="{if (ends-with(current-grouping-key(), 's') then concat(current-grouping-key(), 'es') else concat(current-grouping-key(), 's')}">
       <xsl:copy-of select="current-group()"/>
     </xsl:element>
   </xsl:for-each-group>
 </xsl:copy>
</xsl:template>

<xsl:output indent="yes"/>

这应该会给你一个想法。