2010-11-12 65 views
1

我有一個看起來像這樣的XML文檔。從重複的XML信息中選擇一次,顯示其餘的信息並對字段進行排序

<Results> 
    <Name>Lab Asst1 </Name> 
    <Subject> Math </Subject> 
    <Marks>96</Marks> 
    <Grade>A</Grade> 

    <Name>Student1</Name> 
    <Subject>Math</Subject> 
    <Marks>90</Marks> 
    <Grade>A</Grade> 

    <Name>Student1</Name> 
    <Subject>English</Subject> 
    <Marks>70</Marks> 
    <Grade>B</Grade> 

    <Name>Lab Asst1 </Name> 
    <Subject> Science</Subject> 
    <Marks>99</Marks> 
    <Grade>A</Grade> 

    <Name>Student2</Name> 
    <Subject>Science</Subject> 
    <Marks>70</Marks> 
    <Grade>B</Grade> 

    </Results> 

使用XSL是什麼顯示最簡單的方法,沒有表現出兩倍<Name>元素?我想首先顯示實驗室Asst1結果,假設有一個使用這個值的文本框(從C#代碼進來): 基本上,東西做這部分首先:

User: <Name> 
    Your results are: 
    <table> 
    <tr> 
    <td> Subject </td> 
    <td> Marks </td> 
    <td> Grade </td> 
    </tr> 

然後調用另外一個模板等,或做的for-each或東西....

<tr> 
    <td> <xsl:value-of select="Subject"/> </td> 
    <td> <xsl:value-of select="Marks"/> </td> 
    <td> <xsl:value-of select="Grade"/> </td> 
    </tr> 

,使得我的結果顯示如下:

User: Lab Asst1 
     Your results are: 
     Subject | Marks | Grade 
    ------------------------------------- 
     Science| 99 | A 
      Math | 96 | A 


     User:Student1 
     Your results are: 
     Subject | Marks | Grade 
    ----------------------------- 
      Math | 95 | A 
     English | 70 | B 

     User:Student2 
     Your results are: 
     Subject | Marks | Grade 
    ----------------------------- 
      Math | 70 | B 
+0

您是否擁有對XML的控制權?如果每組數據都包含在它自己的「Result」元素中,那麼處理起來會更容易。 – Oded 2010-11-12 17:53:03

+0

好的,我剛剛做到了。每一個元素,現在看起來是這樣的: 2010-11-12 18:01:30

+0

問得好,+1。查看我的答案,獲得完整有效的解決方案。 :) – 2010-11-12 18:06:30

回答

2

這種轉化On ñ

<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="kPersByName" match="Name" use="."/> 
<xsl:key name="kData" match="*" 
      use="preceding-sibling::Name[1]"/> 

<xsl:template match="/*"> 
    <xsl:for-each select= 
    "Name[generate-id() 
     = 
     generate-id(key('kPersByName', .)[1]) 
     ] 
    "> 
    <xsl:variable name="vData" select="key('kData', .)"/> 

    User: <xsl:value-of select="."/> 
    Your results are: 
    <table border="1"> 
     <tr> 
     <td> Subject </td> 
     <td> Marks </td> 
     <td> Grade </td> 
     </tr> 

     <xsl:for-each select="$vData[self::Subject]"> 
     <tr> 
      <td><xsl:value-of select="."/></td> 
      <td><xsl:value-of select="following-sibling::Marks[1]"/></td> 
      <td><xsl:value-of select="following-sibling::Grade[1]"/></td> 
     </tr> 
     </xsl:for-each> 
    </table> 
    </xsl:for-each> 
</xsl:template> 
</xsl:stylesheet> 

當應用於提供的XML文檔

<Results> 
    <Name>Lab Asst1 </Name> 
    <Subject> Math </Subject> 
    <Marks>96</Marks> 
    <Grade>A</Grade> 

    <Name>Student1</Name> 
    <Subject>Math</Subject> 
    <Marks>90</Marks> 
    <Grade>A</Grade> 

    <Name>Student1</Name> 
    <Subject>English</Subject> 
    <Marks>70</Marks> 
    <Grade>B</Grade> 

    <Name>Lab Asst1 </Name> 
    <Subject> Science</Subject> 
    <Marks>99</Marks> 
    <Grade>A</Grade> 

    <Name>Student2</Name> 
    <Subject>Science</Subject> 
    <Marks>70</Marks> 
    <Grade>B</Grade> 
</Results> 

產生想要的,正確的結果

User: Lab Asst1 
    Your results are: 
    <table border="1"> <tr> 
     <td> Subject </td> 
     <td> Marks </td> 
     <td> Grade </td> 
    </tr> 
    <tr> 
     <td> Math </td> 
     <td>96</td> 
     <td>A</td> 
    </tr> 
    <tr> 
     <td> Science</td> 
     <td>99</td> 
     <td>A</td> 
    </tr> 
</table> 

    User: Student1 
    Your results are: 
    <table border="1"> 
    <tr> 
     <td> Subject </td> 
     <td> Marks </td> 
     <td> Grade </td> 
    </tr> 
    <tr> 
     <td>Math</td> 
     <td>90</td> 
     <td>A</td> 
    </tr> 
    <tr> 
     <td>English</td> 
     <td>70</td> 
     <td>B</td> 
    </tr> 
</table> 

    User: Student2 
    Your results are: 
    <table border="1"> 
    <tr> 
     <td> Subject </td> 
     <td> Marks </td> 
     <td> Grade </td> 
    </tr> 
    <tr> 
     <td>Science</td> 
     <td>70</td> 
     <td>B</td> 
    </tr> 
</table> 

請注意

  1. 使用Muenchian method for grouping

  2. 在XSLT 2.0中,使用<xsl:for-each-group>指令更容易和更方便。

+0

+1很好的答案。 – 2010-11-12 19:09:36

+0

非常感謝你!我嘗試使用XSLT 2.0和按照您的建議使其稍微簡單一些,但似乎我不能在XSLT 2.0元素中使用。淨,但我已經提到!有一個編譯錯誤:System.Xml.Xsl.XslTransformException:'group-by'不是一個可識別的擴展元素。 – 2010-11-16 00:23:21

+0

@Amy:Microsoft沒有XSLT 2.0處理器。在.NET中,如果有人控制服務器環境並允許安裝它,則可以使用Saxon.NET。另外,還有XQSharp(仍在測試版)。 – 2010-11-16 02:07:26