0

I 投票付きの 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が生成されます。

1 つの値 (「勝者」) だけが必要な場合は、たとえば<xsl:if test="position() = 1">...</xsl:if>for-each 内で使用できます。

于 2013-10-31T08:30:54.283 に答える
1

このソリューションは、@Jirka の XSLT 1.0 アプローチと、複数の最良の投票に関する私のコメントを組み合わせて、単純にすべての最良の投票のリストを出力します。準備ステップを使用して最良の投票数を決定し、2 番目のステップで最良の投票数を持つすべての投票を選択します。2 番目のステップでは、もう並べ替える必要がないことに注意してください。ただし、必要に応じて、最良の投票の対称性を破る別の賢明な基準があれば、並べ替えを行うことができます。

<?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 はそのうちの 1 つを選択することに注意してください。

于 2013-10-31T01:52:15.833 に答える