0

我的 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>

在这个例子中,第一个描述应该是获胜者的提议。

4

3 回答 3

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>在 for-each 中使用例如。

于 2013-10-31T08:30:54.283 回答
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>
于 2013-11-01T00:20:35.130 回答
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 将只选择其中之一。

于 2013-10-31T01:52:15.833 回答