2008-09-17 20 views
1

私は次のスニペットのような単純なXML文書を持っています。私はいくつかの属性に基づいてこの文書を基本的に 'unpivots'するXSLT変換を書く必要があります。属性に基づいたピボット解除の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> 

はあなたの助けに感謝。

<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="row"> 
    <row A="{$A}" X="{$X}" /> 
    <row A="{$A}" Y="{$Y}" /> 
    <row A="{$A}" Z="{$Z}" /> 
</xsl:template> 

プラス明らか定型:ここ

+0

は、 }構文です。その使用法に関するいくつかのドキュメントを教えてください。私は重要なものを細かくしようとしています –

0

強引な方法のビットがあります。

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のname()とnamespace-uri()を変数に格納し、それらを使って要素を構築すると、要素をハードコードする必要はありません名。 – jelovirt

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:attribute>ではなく<xsl:element>と属性値テンプレート(属性値の{})ではなく、コードが短くなり、生成する結果ドキュメント。他の人は<xsl:element><xsl:attribute>を好む人は、すべてがXSLT命令であるためです。

あなたがXSLT 2.0を使用している場合、助け構文細かな点のカップル、すなわち、XPathの中exceptオペレータと<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> 
関連する問題