2010-11-11 70 views
1

我想要得到的是一個XSLT模板把幾個XML元素值陷入昏迷分隔的字符串是一個單一的輸出元素的值。變換元素的列表到一個逗號分隔的序列

我在教程中找到了幾個例子來爲文本輸出,但沒有用於XML輸出。

樣品輸入:

<People> 
    <Person>John</Person> 
    <Person>Paul</Person> 
    <Person>George</Person> 
    <Person>Ringo</Person> 
</People> 

所需的輸出:

<Output> 
    <People>John,Paul,George,Ringo</People> 
</Output> 

這是我走到這一步:

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

    <xsl:output method="xml" indent="yes"/> 

    <xsl:template match="/"> 
     <xsl:element name="Output"> 
       <xsl:element name="People"> 
         <xsl:for-each select="People/Person"> 
           <xsl:value-of select="."/> 
           <xsl:text>,</xsl:text> 
         </xsl:for-each> 
       </xsl:element> 
     </xsl:element> 
    </xsl:template> 

</xsl:stylesheet> 

但我不`噸知道如何擺脫最後的昏迷使用這種方法。有任何想法嗎?

+0

到目前爲止你得到了什麼? – Oded 2010-11-11 11:52:59

+0

好問題,+1。看到我的答案是一個通用的簡短(僅限1個模板)解決方案,不依賴於結構依賴性。它也不使用任何明確的條件邏輯指令。 – 2010-11-11 17:14:35

回答

2

這應該工作:

<?xml version="1.0" encoding="ISO-8859-1"?> 

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

<xsl:template match="/"> 
<Output> 
<People> 
    <xsl:apply-templates select="People/Person" /> 
</People> 
</Output> 
</xsl:template> 

<xsl:template match="Person"> 
    <xsl:value-of select="normalize-space(.)" /><xsl:if test="following-sibling::Person">,</xsl:if> 
</xsl:template> 

</xsl:stylesheet> 

注:這不會圍繞每個值行情產生CSV。

+0

以下兄弟斧頭比多個模板更好(但應該是'follow-sibling :: Person' imho),OP應該使用這個。該死的我已經離開XSL太久了。 – annakata 2010-11-11 12:15:07

+0

@annakata - 公平的評論。答案已更新。 – Oded 2010-11-11 12:34:17

3

該轉化

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 
<xsl:strip-space elements="*"/> 

<xsl:template match="/*"> 
    <People> 
    <xsl:apply-templates/> 
    </People> 
</xsl:template> 

<xsl:template match="Person"> 
    <xsl:value-of select= 
    "concat(., 
      substring(',', 1 div not(position()=last())) 
      )"/> 
</xsl:template> 
</xsl:stylesheet> 

當施加到所提供的XML文檔

<People> 
    <Person>John</Person> 
    <Person>Paul</Person> 
    <Person>George</Person> 
    <Person>Ringo</Person> 
</People> 

產生想要的結果

<People>John,Paul,George,Ringo</People> 

請注意:假設序列中的項目之間

  1. 沒有結構性的依賴關係 - 比如,我們不使用的事實,他們是兄弟。

  2. 上述事實使得我們的轉換更加通用 - 它可用於序列中的項不是兄弟或甚至屬於多個XML文檔的情況。

  3. 一個聰明的XPath 1.0特技有助於避免具有不同模板用於第一/最後一個項目和用於其餘:

在XPath 1.0 true()false()被轉換爲10

1 div 0positive-infinitysubstring(anyString, 1, $x)其中$xpositive-infinity,是完整的字符串。