使用XSLT1.0将子属性分组为XML

时间:2016-07-06 12:10:34

标签: xslt xslt-1.0

我现在是XSLT,我需要对孩子的价值进行一些分组。我有对象,可以有多个属性,其中一个(id = 11)是我需要用作分组元素。每个对象可以具有的属性数量各不相同,但它们都具有共同的支柱。

输入:

<object id=1>
 <properties>
    <prop id=10>Name of object 1</prop>
    <prop id=11>Group 1</prop>
    <prop id=xy>Whatever properties this object has</prop>
 </properties>
</object>
<object id=2>
 <properties>
    <prop id=10>Name of object 2</prop>
    <prop id=11>Group 2</prop>
 </properties>
</object>
<object id=3>
 <properties>
    <prop id=10>Name of object 3</prop>
    <prop id=11>Group 1</prop>
 </properties>
</object>
<object id=4>
 <properties>
    <prop id=10>Name of object 4</prop>
    <prop id=11>Group 3</prop>
 </properties>
</object>

期望的输出:

<group name='Group 1'>
  <object id=1>
    <prop id=10>Name of object 1</prop>
    <prop id=11>Group 1</prop>
    <prop id=xy>Whatever properties this object has</prop>
  </object>
<object id=3>
 <properties>
    <prop id=10>Name of object 3</prop>
    <prop id=11>Group 1</prop>
 </properties>
</object>
</group>
<group name='Group 2'>
  <object id=2>
   <properties>
    <prop id=10>Name of object 2</prop>
    <prop id=11>Group 2</prop>
   </properties>
  </object>
</group>
<group name='Group 3'>
  <object id=4>
   <properties>
    <prop id=10>Name of object 4</prop>
    <prop id=11>Group 3</prop>
   </properties>
  </object>
</group>

这个想法是让项目按照id为11的道具的值进行分组。

我发现了多个不同的代码示例,但没有一个具有此特定情况,我无法修改它们以满足我的需要。

2 个答案:

答案 0 :(得分:2)

我的xsl版本与Michael Vehrs基本相同,因为它也使用了Muenchian方法,但我认为我也可以发布它以显示一个微妙的替代方案。在这里,我使用了apply-templates而不是for-each / call-template。在性能方面,它们之间可能没有任何内容,但就个人而言,我更愿意尽可能使用apply-templates,因为它通常允许更多的灵活性。

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="no" encoding="utf-8"/>
<xsl:key name="groups" match="prop[@id='11']" use="text()"/>

<xsl:template match="/">
    <xsl:apply-templates select="//prop[generate-id()=generate-id(key('groups', text())[1])]"/>
</xsl:template>

<xsl:template match="prop">
    <group name="{text()}">
        <xsl:copy-of select="//object[properties/prop[@id='11']=current()/text()]"/>
    </group>
</xsl:template>

</xsl:stylesheet>

答案 1 :(得分:1)

这是 Muenchian方法的基本应用(例如here解释):

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:key name="prop" match="//prop[@id='11']/text()" use="." />

<xsl:template match="/">
  <xsl:for-each select="//prop[@id='11']/text()[generate-id()
                        = generate-id(key('prop',.)[1])]">
    <xsl:call-template name="group">
      <xsl:with-param name="groupname" select="." />
    </xsl:call-template>
  </xsl:for-each>
</xsl:template>

<xsl:template name="group">
  <xsl:param name="groupname" />
  <group><xsl:attribute name="name"><xsl:value-of select='$groupname'/></xsl:attribute>
  <xsl:for-each select="//object[.//prop[@id='11'][text()=$groupname]]" >
    <xsl:copy-of select="." />
  </xsl:for-each>
  </group>
</xsl:template>

</xsl:stylesheet>