假设我有以下XML文件:
<Persons>
<Person>
<Name>A</Name>
<LastName>AAA</LastName>
</Person>
<Person>
<Name>B</Name>
<LastName>BBB</LastName>
</Person>
<Person>
<Name>C</Name>
<LastName>AAA</LastName>
</Person>
<Person>
<Name>D</Name>
<LastName>AAA</LastName>
</Person>
<Person>
<Name>E</Name>
<LastName>BBB</LastName>
</Person>
</Persons>
我需要生成一个包含所有系列(姓氏)的表格,以及每个姓氏的人数。至于示例,该表应如下所示:
家庭 - 人
AAA - 3
BBB - 2
如何制作一个可以在每个姓氏上运行的循环?
答案 0 :(得分:1)
有很多方法可以做到这一点,这是一种方法。它使用Muenchian grouping(谢谢,Michael),它(相对)直截了当。如果您需要指导理解代码,则应该从tutorial on matching templates,keys或grouping with for-each开始(本示例中未使用)。
以下代码为每个count
添加了Person
个属性,以确定有多少人具有相同的姓氏:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output indent="yes" />
<xsl:key match="LastName" use="text()" name="lastname" />
<xsl:template match="/Persons">
<xsl:copy>
<xsl:apply-templates />
</xsl:copy>
</xsl:template>
<xsl:template match="Person[generate-id() = key('lastname', LastName)[1]]">
<xsl:copy>
<xsl:attribute name="count">
<xsl:value-of select="count(key('lastname', current()/LastName))" />
</xsl:attribute>
<xsl:copy-of select="*" />
</xsl:copy>
</xsl:template>
<!-- remove nodes we are not interested in, incl. whitespace only text nodes -->
<xsl:template match="node()" >
<xsl:apply-templates />
</xsl:template>
</xsl:stylesheet>
根据您的输入,它会生成:
<?xml version="1.0" encoding="UTF-8"?>
<Persons>
<Person count="3">
<Name>A</Name>
<LastName>AAA</LastName>
</Person>
<Person count="2">
<Name>B</Name>
<LastName>BBB</LastName>
</Person>
</Persons>
PS:在XSLT 2.0中,使用xsl:for-each-group
可以轻松实现同样的目标。
答案 1 :(得分:0)
我过去发现的最简单的方法就是使用一种名为Muenchian Grouping的技术。详细信息在这里(http://www.jenitennison.com/xslt/grouping/muenchian.html)。该技术包括首先生成您的唯一键(在您的情况下为姓),然后选择符合该键的元素。