使用下面的
XML,我需要弄清楚哪个人在每个站点工作的时间更长.例如,在下面的XML中,人1在站点1中工作8小时但是人2工作仅6小时.因此,结果应包含转换后的XML中的person 1和site 1.如果小时数相等,请选择第一个人.
编辑:我希望使用XSLT 1.0实现.
<root> <WorkSite Person="P1" Site="S1"> <Hours>8</Hours> </WorkSite> <WorkSite Person="P1" Site="S2"> <Hours>2</Hours> </WorkSite> <WorkSite Person="P1" Site="S3"> <Hours>9</Hours> </WorkSite> <WorkSite Person="P2" Site="S1"> <Hours>6</Hours> </WorkSite> <WorkSite Person="P2" Site="S2"> <Hours>10</Hours> </WorkSite> <WorkSite Person="P2" Site="S3"> <Hours>2</Hours> </WorkSite> </root>
XSLT转换结果应如下所示:
<root> <WorkSite Person="P1" Site="S1"/> <WorkSite Person="P2" Site="S2"/> <WorkSite Person="P1" Site="S3"/> </root>
解决方法
这个XSLT 1.0转换:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output omit-xml-declaration="yes" indent="yes"/> <xsl:key name="kSiteByName" match="@Site" use="."/> <xsl:key name="kWorksiteBySite" match="WorkSite" use="@Site"/> <xsl:variable name="vSites" select= "/*/*/@Site[generate-id() = generate-id(key('kSiteByName',.)[1]) ]" /> <xsl:template match="/"> <root> <xsl:for-each select="$vSites"> <xsl:for-each select="key('kWorksiteBySite',.)"> <xsl:sort select="Hours" data-type="number" order="descending"/> <xsl:if test="position()=1"> <xsl:copy> <xsl:copy-of select="@*"/> </xsl:copy> </xsl:if> </xsl:for-each> </xsl:for-each> </root> </xsl:template> </xsl:stylesheet>
当应用于提供的XML文档时:
<root> <WorkSite Person="P1" Site="S1"> <Hours>8</Hours> </WorkSite> <WorkSite Person="P1" Site="S2"> <Hours>2</Hours> </WorkSite> <WorkSite Person="P1" Site="S3"> <Hours>9</Hours> </WorkSite> <WorkSite Person="P2" Site="S1"> <Hours>6</Hours> </WorkSite> <WorkSite Person="P2" Site="S2"> <Hours>10</Hours> </WorkSite> <WorkSite Person="P2" Site="S3"> <Hours>2</Hours> </WorkSite> </root>
产生想要的,正确的结果:
<root> <WorkSite Person="P1" Site="S1"/> <WorkSite Person="P2" Site="S2"/> <WorkSite Person="P1" Site="S3"/> </root>
请注意:
>使用Muenchian方法进行分组以查找所有不同的Site值.>通过按降序排序并从排序的节点列表中获取第一个结果来找到最大值的方式.