2012-03-20 86 views
2

我試圖檢索第一個唯一的2個屬性集。XSLT檢索第一個唯一值

我正在尋找每個學生的名字與他的第一個獨特的組。如果對於學生來說第一組已經被任何學生佔用,則應該列出下一個獨特的組。我發佈了我的XML和預期結果XML。

我需要XSLT語句才能得到這個結果(版本1.0)。謝謝。

這裏是我的xml結構

<Socrates> 
<Student name='Aristotle' group='1' /> 
<Student name='Aristotle' group='2' /> 
<Student name='Aristotle' group='3' /> 
<Student name='Aristotle' group='4' /> 

<Student name='Plato' group='1' /> 
<Student name='Plato' group='2' /> 
<Student name='Plato' group='3' /> 

<Student name='Xenophon' group='4' /> 
<Student name='Xenophon' group='5' /> 
<Student name='Xenophon' group='6' /> 

<Student name='Critias' group='1' /> 
<Student name='Critias' group='2' /> 
<Student name='Critias' group='3' />  
<Student name='Critias' group='4' /> 
<Student name='Critias' group='5' /> 
<Student name='Critias' group='6' /> 
    </Socrates> 

結果XML

<Socrates> 
    <Student name='Aristotle' group='1' /> 
<Student name='Plato' group='2' /> 
<Student name='Xenophon' group='4' /> 
<Student name='Critias' group='3' /> 
</Socrates> 
+0

難道你不想讓最後一項成爲「@ group =」5「'? – 2012-03-21 00:42:03

+0

@MadsHansen:感謝您的評論和回答。我還沒有測試過你的答案,但我需要最後一個成爲第3組,因爲它還沒有被其他學生選中。一旦我能夠測試你的答案,將會更新你。謝謝! – 2012-03-21 17:18:39

+1

這樣一個複雜的問題應該至少包含更多的示例以及指定的xslt目標版本。 – 2012-03-21 21:09:40

回答

2

另一種略有不同的方法(雖然不一定是更好的方法)是一個參數傳遞到其中包含了每個學生比賽以逗號分隔的已經輸出的屬性。每當你匹配一個學生時,你檢查他們的組是否在他的參數中,如果沒有輸出學生,並獲得下一個,則將當前組附加到參數。

這裏是XSLT,這是我的評論,試圖解釋事情做得更好

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output indent="yes"/> 

    <xsl:template match="Socrates"> 
     <Socrates> 
     <xsl:apply-templates select="Student[1]"/> 
     </Socrates> 
    </xsl:template> 

    <xsl:template match="Student"> 
     <!-- Parameter containin comma-delimited list of currently output groups --> 
     <xsl:param name="groupList" select="','" /> 
     <xsl:choose> 
     <!-- Has the group already been output? --> 
     <xsl:when test="contains($groupList, concat(',', @group, ','))"> 
      <!-- If so, move on to next student record --> 
      <xsl:apply-templates select="following-sibling::Student[1]"> 
       <xsl:with-param name="groupList" select="$groupList" /> 
      </xsl:apply-templates> 
     </xsl:when> 
     <!-- Group has not already been output --> 
     <xsl:otherwise> 
      <!-- Output the record --> 
      <xsl:copy-of select="." /> 

      <!-- Get the next student with a different name --> 
      <xsl:apply-templates select="following-sibling::Student[@name!=current()/@name][1]"> 
       <xsl:with-param name="groupList" select="concat($groupList, @group, ',')" /> 
      </xsl:apply-templates> 
     </xsl:otherwise> 
     </xsl:choose> 
    </xsl:template> 
</xsl:stylesheet> 

當適用於您的示例XML,下面是輸出

<Socrates> 
    <Student name="Aristotle" group="1" /> 
    <Student name="Plato" group="2" /> 
    <Student name="Xenophon" group="4" /> 
    <Student name="Critias" group="3" /> 
</Socrates> 

請注意,這並承擔學生元素總是按輸入XML中的名稱排序。

+0

謝謝!這當然看起來不錯。我還沒有能夠測試它。它適用於XSLT 1.0嗎? – 2012-03-22 17:58:35

+0

這實際上是一個XSLT 1.0解決方案。 – 2012-03-22 22:37:54