2012-07-10 77 views
2

我有下面的XML文檔:XSLT逗號元素脫離

<?xml version="1.0" encoding="UTF-8"?> 
<cars> 
    <car> 
     <entrydata columnnumber="4" name="Colour"> 
      <text>Red</text> 
     </entrydata> 
    </car> 
    <car> 
     <entrydata columnnumber="4" name="Colour"> 
      <textlist> 
       <text>Yellow</text> 
       <text>Blue</text> 
      </textlist> 
     </entrydata> 
    </car> 
</cars> 

和以下XSLT樣式表:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com: xslt" exclude-result-prefixes="msxsl"> 
    <xsl:output method="xml" indent="yes"/> 
    <xsl:template match="/"> 
    <records> 
     <xsl:apply-templates select="//cars"/> 
    </records> 
    </xsl:template> 
    <!--Top level template --> 
    <xsl:template match="cars"> 
    <!-- Loop through each document (viewentry) and apply create the rows for each one--> 
    <xsl:for-each select="car"> 
     <record> 
     <xsl:attribute name="Colour"> 
      <xsl:value-of select="entrydata[@name='Colour']"/> 
     </xsl:attribute> 
     </record> 
    </xsl:for-each> 
    </xsl:template> 
</xsl:stylesheet> 

這將產生以下輸出:

<?xml version="1.0" encoding="UTF-8"?> 
<records> 
    <record Colour="Red"/> 
    <record Colour="YellowBlue"/> 
</records> 

我將如何修改XSLT文件,以便輸出變爲(注意<textlist>逗號分隔):

<?xml version="1.0" encoding="UTF-8"?> 
<records> 
    <record Colour="Red"/> 
    <record Colour="Yellow, Blue"/> 
</records> 
+0

這是一個起點:http://www.xsltcake.com/slices/t4nxk9/2 – joshcomley 2012-07-10 09:52:59

回答

2

一個不那麼冗長,純粹的「推式」 XSLT 1.0解決方案,不使用硬編碼字符串所生成的屬性的名稱:

<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="cars"> 
    <records> 
     <xsl:apply-templates/> 
    </records> 
</xsl:template> 
<xsl:template match="car"> 
    <record> 
    <xsl:apply-templates/> 
    </record> 
</xsl:template> 
<xsl:template match="entrydata"> 
    <xsl:attribute name="{@name}"> 
    <xsl:apply-templates/> 
    </xsl:attribute> 
</xsl:template> 
<xsl:template match="text"> 
    <xsl:if test="position() >1">, </xsl:if> 
    <xsl:value-of select="."/> 
</xsl:template> 
</xsl:stylesheet> 

當這個變換所提供的XML文檔應用:

<cars> 
    <car> 
     <entrydata columnnumber="4" name="Colour"> 
      <text>Red</text> 
     </entrydata> 
    </car> 
    <car> 
     <entrydata columnnumber="4" name="Colour"> 
      <textlist> 
       <text>Yellow</text> 
       <text>Blue</text> 
      </textlist> 
     </entrydata> 
    </car> 
</cars> 

的想要的,正確的結果產生

<records> 
    <record Colour="Red"/> 
    <record Colour="Yellow, Blue"/> 
</records> 

說明

正確使用的模板,模式匹配,AVTS和position()功能。


二,更簡單的XSLT 2。0溶液

<xsl:stylesheet version="2.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="cars"> 
    <records> 
     <xsl:apply-templates/> 
    </records> 
</xsl:template> 
<xsl:template match="car"> 
    <record> 
    <xsl:apply-templates/> 
    </record> 
</xsl:template> 
<xsl:template match="entrydata"> 
    <xsl:attribute name="{@name}"> 
    <xsl:value-of select=".//text" separator=", "/> 
    </xsl:attribute> 
</xsl:template> 
</xsl:stylesheet> 

當這種轉化是在同一個XML文檔(上圖)中,相同的正確的結果產生施加:

<records> 
    <record Colour="Red"/> 
    <record Colour="Yellow, Blue"/> 
</records> 

說明

正確使用的模板,模式匹配,AVT和的separator屬性

2

使用XSLT 2.0,您可以使用

<record Colour="{string-join(entrydata[@name='Colour']/textlist/text, ', ')}"/> 

使用XSLT 1.0,我會做

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com: xslt" exclude-result-prefixes="msxsl"> 
    <xsl:output method="xml" indent="yes"/> 
    <xsl:template match="/"> 
    <records> 
     <xsl:apply-templates select="//cars"/> 
    </records> 
    </xsl:template> 
    <!--Top level template --> 
    <xsl:template match="cars/car"> 
    <record> 
     <xsl:attribute name="Colour"> 
      <xsl:apply-templates select="entrydata[@name='Colour']textlist/text"/> 
     </xsl:attribute> 
     </record> 
    </xsl:template> 
    <xsl:template match="textlist/text"> 
    <xsl:if test="position() > 1"> 
     <xsl:text>, </xsl:text> 
    </xsl:if> 
    <xsl:value-of select="."/> 
    </xsl:template> 
</xsl:stylesheet> 
+0

AVT也可用於XSLT 1.0。 – 2012-07-10 10:26:23

+0

肖恩,如果你想要逗號分隔的幾個節點值的列表,單獨的屬性值模板不會有幫助。相反,使用XSLT/XPath 1.0語義執行''會輸出第一個'text'元素的值,而不是所有。 – 2012-07-10 10:39:06

+0

請參閱我使用AVT的解決方案。我測試過了。有用。 – 2012-07-10 10:41:27

1

這XSLT 1.0樣式表就可以了...

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

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

    <xsl:template match="car"> 
    <xsl:variable name="colour-list"> 
    <xsl:for-each select="entrydata[@name='Colour']/text | 
          entrydata[@name='Colour']/textlist/text"> 
     <xsl:value-of select="concat(.,', ')" /> 
    </xsl:for-each> 
    </xsl:variable> 
     <record Colour="{substring($colour-list,1,string-length($colour-list)-2)}"/> 
    </xsl:template> 
</xsl:stylesheet> 

但對於簡單的解決贏家是這樣的XSLT 2.0樣式表...

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

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

<xsl:template match="car"> 
<record Colour="{string-join(entrydata[@name='Colour']/(text | textlist/text),', ')}"/> 
</xsl:template> 
</xsl:stylesheet>