2012-08-07 71 views
1

我有以下結構:存在並遍歷它們的值

League 

----Clubs 

---------Club 

-------------Players 

--------------------Player 

--------------------------FirstName 

--------------------------Surname etc 

--------------------Player 

--------------------------FirstName 

--------------------------Surname etc 

---------Club 

-------------Players 

--------------------Player 

--------------------------FirstName 

--------------------------Surname etc 

--------------------Player 

--------------------------FirstName 

--------------------------Surname etc 

無論如何 - 我想獲得的所有球員的名字在我的XSLT轉換(我使用BizTalk映射所以必須堅持使用XSLT1 - 我喜歡使用內聯XSLT而不是映射器工具,因爲我轉換的XML在沒有俱樂部球員的情況下期望沒有屬性(在這種情況下有一個俱樂部,但也我保持這一點,以備將來打樣)

下面是我試過的一個粗略示例:

<xsl:template name="PlayerNames"> 
    <xsl:element name="ns0:PlayersInLeague"> 
<xsl:element name="ns0:Team> 
    <xsl:choose> 
    <xsl:when test="current()/*[local-name()='Players']/*[local-name()='Player']"> 
    <xsl:for-each select="current()/*[local-name()='Players']/*[local-name()='Player']"> 
     <xsl:element name="ns0:Player"><xsl:value-of select="current()/*[local-name()='FirstName']"/></xsl:element> 
    </xsl:for-each> 
    </xsl:when> 
    <xsl:otherwise> 
     <xsl:attribute name="xsi:nil">true</xsl:attribute> 
    </xsl:otherwise> 
    </xsl:choose> 
    </xsl:element> 
    </xsl:element> 
    </xsl:template> 

我想沿着這些線路的輸出:

PlayersInLeague

----團隊

------弗雷德

------大衛

---- Team xsi:nil = true

---- Team

------亞歷

------湯姆

<league> 
<clubs> 
<club name="London"> 
<players> 
<player> 
<firstname>fred</firstname> 
</player> 
<player> 
<firstname>david</firstname> 
</player> 
</players> 
</club> 
<club name="Madrid"> 
<players/> 
</club> 
<club name="Amsterdam"> 
<players> 
<player> 
<firstname>Alex</firstname> 
</player> 
<player> 
<firstname>Tom</firstname> 
</player> 
</players> 
</club> 
</clubs> 
</league> 

輸入我不是什麼當前()命令完全確定正在做,我已經去了很多次,我看不出現在怎麼改正 - 任何人都可以幫忙嗎?

回答

1

在XSLT中,您通常希望使用模式匹配來區分不同的情況。在這裏,你可以製作兩個模板 - 一個用於空的俱樂部,另一個用於常規俱樂部。

它很冗長,但是一旦忘記for-loops,它實際上非常清晰。

編輯:現在,我認爲如果我組織模板反向會更有意義。所以,請從下往上閱讀樣式表。抱歉。 ;-)

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" > 
    <xsl:template match="player"> <!-- only display firstname contents --> 
     <xsl:copy> 
      <xsl:apply-templates select="firstname"/> 
     </xsl:copy> 
    </xsl:template> 
    <xsl:template match="club"> <!-- default club template --> 
     <team> 
      <xsl:apply-templates/> 
     </team> 
    </xsl:template> 
    <xsl:template match="club[not(players/player)]"> <!-- empty club template --> 
     <team> 
      <xsl:attribute name="nil" namespace="http://www.w3.org/2001/XMLSchema-instance">true</xsl:attribute> 
     </team> 
    </xsl:template> 
    <xsl:template match="/"> <!-- entry template --> 
     <PlayersInLeague> 
      <xsl:apply-templates/> 
     </PlayersInLeague> 
    </xsl:template> 
</xsl:stylesheet> 
+0

謝謝!然而,我很困惑,這是如何: 知道我想要 Fred例如?或者我必須添加一個單獨的模板?從來沒有真正處理過很多模板等 – Chris 2012-08-07 11:05:18

+1

默認情況下會包含在firstname元素(但不包含元素)下找到的所有文本。 xsl:copy-of應該照原樣複製整個子樹。 – Krab 2012-08-07 12:15:48

+0

XSLT基於模板。它們在引擎經過輸入XML時(當它們匹配當前節點時)應用。所以真正控制執行的是輸入文檔。 – Krab 2012-08-07 12:16:15

相關問題