2015-01-05 82 views
0

我想將唯一的XML子元素值添加到選擇列表。以下是我迄今爲止將唯一的XML元素值添加到選擇列表

XML:

<Student> 
    <record> 
    <Name>Jack</Name> 
    </record> 
    <record> 
    <Name>Jack</Name> 
    </record> 
    <record> 
    <Name>John</Name> 
    </record> 
    <record> 
    <Name>John</Name> 
    </record> 
    <record> 
    <Name>John</Name> 
    </record> 
    <record> 
    <Name>Jill</Name> 
    </record> 
    <record> 
    <Name>Jill</Name> 
    </record> 
    <record> 
    <Name>James</Name> 
    </record> 
</Student> 

XSLT:

<xsl:key name="NameKey" match="Name" use="."/> 

    <xsl:template match="Student"> 
    <table> 
     <tr> 
     <th>Name</th> 
     <td> 
      <select> 
       <xsl:for-each select="record"> 
       <option> 
       <xsl:element name="Name"> 
        <xsl:value-of select="Name[generate-id() = generate-id(key('NameKey',.)[1])]" /> 
       </xsl:element> 
       </option> 
       </xsl:for-each>    
      </select> 
     </td> 
     </tr> 
     <xsl:apply-templates select="/record" /> 
    </table> 
    </xsl:template> 
</xsl:stylesheet> 

我成功獲得唯一值列表,但名單還顯示爲空字符串列表中的非唯一值。所以我的名單有以下值:

Jack 

John 


Jill 

James 

有沒有什麼辦法擺脫列表中的那些空字符串值?

+0

請向我們展示一個XML輸入示例,以便我們可以重現該問題。 - P.S.我沒有看到你正在收集**屬性**值; *屬性*這個詞在XML中具有非常精確的含義。 –

+0

@ michael.hor257k我已更新我的問題。對不起,我錯了,我的意思是元素值 – user793468

回答

1

有什麼辦法擺脫列表中的空字符串值?

是的,只需將鍵名查找的謂詞移動到xsl:for-each即可。使用您當前的代碼,全部這些節點將交給xsl:for-each,包括重複項。

順便說一句,這條線

<xsl:apply-templates select="/record" /> 

不會做任何事情,因爲最外層的元素節點不叫record。你在這裏有什麼意圖?

XSLT樣式表

<?xml version="1.0" encoding="UTF-8" ?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 

    <xsl:output method="html" encoding="UTF-8" indent="yes" /> 
    <xsl:key name="NameKey" match="Name" use="."/> 

    <xsl:template match="Student"> 
    <table> 
     <tr> 
     <th>Name</th> 
     <td> 
      <select> 
       <xsl:for-each select="record/Name[generate-id() = generate-id(key('NameKey',.)[1])]"> 
       <option> 
       <xsl:element name="Name"> 
        <xsl:value-of select="." /> 
       </xsl:element> 
       </option> 
       </xsl:for-each>    
      </select> 
     </td> 
     </tr> 
     <xsl:apply-templates select="/record" /> 
    </table> 
    </xsl:template> 
</xsl:stylesheet> 

HTML輸出

<table> 
    <tr> 
     <th>Name</th> 
     <td> 
     <select> 
      <option> 
       <Name>Jack</Name> 
      </option> 
      <option> 
       <Name>John</Name> 
      </option> 
      <option> 
       <Name>Jill</Name> 
      </option> 
      <option> 
       <Name>James</Name> 
      </option> 
     </select> 
     </td> 
    </tr> 
</table> 

呈現的HTML

enter image description here

+0

謝謝!我刪除了「」行 – user793468

1

我想補充一點,這也可以通過使用[not(.=preceding::*)]來實現。

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 

    <xsl:output method="html" encoding="UTF-8" indent="yes" /> 

    <xsl:template match="Student"> 
     <table> 
      <tr> 
       <th>Name</th> 
       <td> 
        <select> 
         <xsl:for-each select="record/Name[not(.=preceding::*)]"> 
          <option> 
           <xsl:element name="Name"> 
            <xsl:value-of select="." /> 
           </xsl:element> 
          </option> 
         </xsl:for-each>    
        </select> 
       </td> 
      </tr> 
      <xsl:apply-templates select="/record" /> 
     </table> 
    </xsl:template> 
</xsl:stylesheet> 

我個人認爲這樣更清楚你只處理每個Name元素一次。

+0

這不是一個好方法 - 請看這裏why:http://www.jenitennison.com/xslt/grouping/muenchian.html –