我是XML文档,有投票。我必须知道更多选票的建议是什么,我该怎么做? 我正在使用XSLT进行转换,但我无法找到方法。
XML:
<tns:vote>
<tns:alternative>
<tns:description>50% do valor recebido das propinas será aplicado em investigação</tns:description>
<tns:votes>
<tns:member_vote member_id="i2"/>
<tns:member_vote member_id="i6"/>
<tns:member_vote member_id="i7"/>
</tns:votes>
<tns:description>20% do valor recebido das propinas será aplicado em investigação</tns:description>
<tns:votes>
<tns:member_vote member_id="i4"/>
<tns:member_vote member_id="i5"/>
</tns:votes>
</tns:alternative>
</tns:vote>
在这个例子中,第一个描述应该是赢家提议。
答案 0 :(得分:2)
在xslt 1.0中,您可以使用xsl:sort指令,如:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:tns="tns">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="/">
<result>
<xsl:apply-templates select="tns:vote/tns:alternative" />
</result>
</xsl:template>
<xsl:template match="tns:alternative">
<!-- Process all description -->
<xsl:for-each select="tns:description">
<!-- Sort them descending by count votes in the first following sibling tns:votes -->
<xsl:sort select="count(following-sibling::tns:votes[1]/tns:member_vote)" order="descending" />
<!-- Do anything with that, e.g. make a deep copy -->
<xsl:copy-of select="." />
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
生成xml,其描述按投票顺序排序。
如果您只需要一个值(“获胜者”),您可以使用例如每个人都在<xsl:if test="position() = 1">...</xsl:if>
内。
答案 1 :(得分:1)
此解决方案结合了@Jirka的XSLT 1.0方法和我对多个最佳投票的评论,并简单地输出所有最佳投票的列表。它使用准备步骤来确定最佳投票数,然后在第二步中选择具有最佳计数的所有投票。请注意,在第二步中,我们不再需要排序。如果有必要,我们仍然可以进行排序,如果有另一个合理的标准打破最佳选票的对称性。
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
version="1.0"
xmlns:tns="mynamespace"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" />
<xsl:strip-space elements="*"/>
<xsl:template match="/tns:vote/tns:alternative">
<!-- compute the best vote count; just the number not the elements -->
<xsl:variable name="best_vote">
<xsl:for-each select="tns:description">
<xsl:sort select="count(following-sibling::tns:votes[1]/tns:member_vote)" order="descending"/>
<xsl:if test="position() = 1">
<xsl:value-of select="count(following-sibling::tns:votes[1]/tns:member_vote)"/>
</xsl:if>
</xsl:for-each>
</xsl:variable>
<tns:result>
<xsl:for-each select="tns:description"> <!-- we need not sort here anymore! -->
<!-- only dump those entries which match the best vote count -->
<xsl:if test="count(following-sibling::tns:votes[1]/tns:member_vote) = number($best_vote)">
<tns:winning_vote vote_count="{count(following-sibling::tns:votes[1]/tns:member_vote)}">
<xsl:copy-of select="."/>
<xsl:copy-of select="following-sibling::tns:votes[1]/tns:member_vote"/>
</tns:winning_vote>
</xsl:if>
</xsl:for-each>
</tns:result>
</xsl:template>
</xsl:stylesheet>
答案 2 :(得分:0)
在XSLT 2.0中,您可以将for-each-group
标记与sort
一起使用。以下XSLT
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
version="2.0"
xmlns:tns="mynamespace"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" />
<xsl:template match="/tns:vote/tns:alternative">
<xsl:for-each-group select="*" group-starting-with="tns:description">
<xsl:sort select="count(current-group()[2]/tns:member_vote)" order="descending"/>
<xsl:if test="position() = 1">
<tns:winning_alternative vote_count="{count(current-group()[2]/tns:member_vote)}>
<xsl:copy-of select="current-group()"/>
</tns:winning_alternative>
</xsl:if>
</xsl:for-each-group>
</xsl:template>
</xsl:stylesheet>
产生此结果
<?xml version="1.0" encoding="UTF-8"?>
<tns:winning_alternative xmlns:tns="mynamespace" vote_count="3">
<tns:description>50% do valor recebido das propinas será aplicado em investigação</tns:description>
<tns:votes>
<tns:member_vote member_id="i2"/>
<tns:member_vote member_id="i6"/>
<tns:member_vote member_id="i7"/>
</tns:votes>
</tns:winning_alternative>
请注意,如果多个替代方案具有相同的最佳投票,XSLT将只选择其中一个。