2008-09-17 99 views
1

我有一個簡單的xml文檔,看起來像下面的代碼片段。我需要編寫一個XSLT轉換,它基於一些屬性基本上'未轉換'該文檔。基於屬性的Unpivot xml文檔

<?xml version="1.0" encoding="utf-8" ?> 
<root xmlns:z="foo"> 
    <z:row A="1" X="2" Y="n1" Z="500"/> 
    <z:row A="2" X="5" Y="n2" Z="1500"/> 
</root> 

這是我所希望輸出是 -

<?xml version="1.0" encoding="utf-8" ?> 
<root xmlns:z="foo"> 
    <z:row A="1" X="2" /> 
    <z:row A="1" Y="n1" /> 
    <z:row A="1" Z="500"/> 
    <z:row A="2" X="5" /> 
    <z:row A="2" Y="n2"/> 
    <z:row A="2" Z="1500"/> 
</root> 

感謝你的幫助。

回答

1
<xsl:template match="row"> 
    <row A="{$A}" X="{$X}" /> 
    <row A="{$A}" Y="{$Y}" /> 
    <row A="{$A}" Z="{$Z}" /> 
</xsl:template> 

加上明顯的樣板。

+0

我喜歡{ } 句法。你能指點我一些關於他們用法的文檔嗎?我正在努力處理任何重要的事情 – 2008-09-17 21:25:51

0

這是一個有點蠻力方式:

<xsl:template match="z:row"> 
    <xsl:element name="z:row"> 
     <xsl:attribute name="A"> 
      <xsl:value-of select="@A"/> 
     </xsl:attribute> 
     <xsl:attribute name="X"> 
      <xsl:value-of select="@X"/> 
     </xsl:attribute> 
    </xsl:element> 
    <xsl:element name="z:row"> 
     <xsl:attribute name="A"> 
      <xsl:value-of select="@A"/> 
     </xsl:attribute> 
     <xsl:attribute name="Y"> 
      <xsl:value-of select="@Y"/> 
     </xsl:attribute> 
    </xsl:element> 
    <xsl:element name="z:row"> 
     <xsl:attribute name="A"> 
      <xsl:value-of select="@A"/> 
     </xsl:attribute> 
     <xsl:attribute name="Z"> 
      <xsl:value-of select="@Z"/> 
     </xsl:attribute> 
    </xsl:element> 
</xsl:template> 


<xsl:template match="@* | node()"> 
    <xsl:copy> 
     <xsl:apply-templates select="@* | node()"/> 
    </xsl:copy> 
</xsl:template> 

1

這是比較複雜的,但也更通用:

<xsl:template match="z:row"> 
    <xsl:variable name="attr" select="@A"/> 
    <xsl:for-each select="@*[(local-name() != 'A')]"> 
     <xsl:element name="z:row"> 
      <xsl:copy-of select="$attr"/> 
      <xsl:attribute name="{name()}"><xsl:value-of select="."/></xsl:attribute> 
     </xsl:element> 
    </xsl:for-each> 
</xsl:template> 
+0

您還可以將z:row的名稱()和namespace-uri()存儲到變量中,然後使用它們構造元素,這樣就不必對元素進行硬編碼名稱。 – jelovirt 2008-09-18 04:12:28

3

這裏有您需要(因爲命名空間是很重要的),滿樣式表:

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

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

<xsl:template match="z:row"> 
    <xsl:variable name="A" select="@A" /> 
    <xsl:for-each select="@*[local-name() != 'A']"> 
    <z:row A="{$A}"> 
     <xsl:attribute name="{local-name()}"> 
     <xsl:value-of select="." /> 
     </xsl:attribute> 
    </z:row> 
    </xsl:for-each> 
</xsl:template> 

</xsl:stylesheet> 

,我更喜歡用文字結果元素(如而不是<xsl:element>而不是<xsl:element>和屬性值模板(屬性值中的那些{} s)而不是<xsl:attribute>在可能的情況下,因爲它使代碼更短,並使得更容易看到您正在生成的結果文檔。其他人更喜歡<xsl:element><xsl:attribute>,因爲那麼一切都是XSLT指令。

如果您使用XSLT 2.0,有幾個語法樂事,幫助,即except運營商XPath和直接在<xsl:attribute>使用select屬性的能力:

<xsl:stylesheet version="2.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    exclude-result-prefixes="xs" 
    xmlns:z="foo"> 

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

<xsl:template match="z:row"> 
    <xsl:variable name="A" as="xs:string" select="@A" /> 
    <xsl:for-each select="@* except @A"> 
    <z:row A="{$A}"> 
     <xsl:attribute name="{local-name()}" select="." /> 
    </z:row> 
    </xsl:for-each> 
</xsl:template> 

</xsl:stylesheet>