2

私はこのようなxmlファイルを持っています:

<products>
    <cars>
        <car>
            <brand>Audi</brand>
            <type>S3</type>
            <attribs>
                <attrib>
                    <color>1</color>
                    <price>45000</price>
                </attrib>
                <attrib>
                    <color>2</color>
                    <price>75000</price>
                </attrib>
                <attrib>
                    <color>4</color>
                    <price>35000</price>
                </attrib>
            </attribs>      
        </car>

        <!-- Many cars following -->

    </cars>
    <colors>
        <color>
            <id>1</id>
            <shortdesc>Blue</shortdesc>
            <description>Blue Lagoon</description>
        </color>
        <color>
            <id>2</id>
            <shortdesc>Red</shortdesc>
            <description>Red Sport</description>
        </color>
        <color>
            <id>3</id>
            <shortdesc>Green</shortdesc>
            <description>Green Forest</description>
        </color>
        <color>
            <id>4</id>
            <shortdesc>Yellow</shortdesc>
            <description>Yellow</description>
        </color>
                <!-- many colors -->
    </colors>
</products>

私はこのXMLをExcelのクロスシートに変換しています。ここでは、車が縦に、色が横に次のようになっています。

Brand / Model       1/Blue   2/Red   3/Green   4/Yellow

Audi S3             45000    75000   -         35000    
Audi S6             66000    68000   59000     -
Jaguar x-type       98000    -       99500     -

xsltは次のようになります。

<ss:Table>
    <ss:Row>
        <!-- This is the header row -->
        <ss:Cell>
            <ss:Data ss:Type="String">Brand / Model</ss:Data>
        </ss:Cell>
        <xsl:for-each select="colors/color">
            <ss:Cell>
                <ss:Data ss:Type="String">
                    <xsl:value-of select="id"/>/<xsl:value-of select="shortdesc"/>
                </ss:Data>
            </ss:Cell>
        </xsl:for-each>
    </ss:Row>
    <xsl:for-each select="cars/car">
        <ss:Row>
            <ss:Cell>
                <ss:Data ss:Type="String">
                    <xsl:value-of select="brand"/> <xsl:value-of select="type"/>
                </ss:Data>
            </ss:Cell>
            <xsl:for-each select="attribs/attrib">
                <!-- I Know this is incorrect, but what to put in the if ? -->
                <xsl:if test="color = /colors/color/id">
                    <ss:Cell>
                        <ss:Data ss:Type="String">
                            <xsl:value-of select="price"/>
                        </ss:Data>
                    </ss:Cell>
                </xsl:if>
                <xsl:if test="color != /colors/color/id">
                    <ss:Cell>
                        <ss:Data ss:Type="String">-</ss:Data>
                    </ss:Cell>
                </xsl:if>
            </xsl:for-each>
        </ss:Row>
    </xsl:for-each>
</ss:Table>

右の列に価格を比較/書き込む方法を探しています。

テンプレートは、車と色の両方にアクセスできるようにするために、ノード/productsを参照しています。考えられる方法は、ヘッダーに色を書き込むと同時に配列を作成し、車を処理するときにそれと比較することです。これは可能な方法ですか、それとももっと良い方法が可能ですか?

別の詳細:XMLはすでにこのように設計されているため、変更できません(実際、処理している車ではなく、単純にするためです)

4

1 に答える 1

3

複合キーを使用して、ブランド、タイプ、および色別に車を収集できます。

<xsl:output indent="yes"/>
<xsl:key name="k_cars" 
    match="/products/cars/car/attribs/attrib" 
    use="concat(../../brand,../../type,color)"/>

次に、繰り返してcars/car、すべての色の価格を確認する必要があるため(一部の車では色が見当たらない場合があります)、繰り返して、キーのテストcolors/colorを使用します。xsl:chooseキーがノードを返す場合は、対応する価格を出力します。それ以外の場合は印刷します-

<xsl:variable name="car" select="."/>

<xsl:for-each select="/products/colors/*">

    <xsl:variable name="v_CarColor" 
        select="key('k_cars',concat($car/brand,$car/type,id))"/>

    <xsl:choose>

        <xsl:when test="$v_CarColor">
            <ss:Cell>
                <ss:Data ss:Type="String">
                    <xsl:value-of select="$v_CarColor/price"/>
                </ss:Data>
            </ss:Cell>
        </xsl:when>

        <xsl:otherwise>
            <ss:Cell>
                <ss:Data ss:Type="String">-</ss:Data>
            </ss:Cell>
        </xsl:otherwise>

    </xsl:choose>
</xsl:for-each>

最終的な変換:

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

    <xsl:output indent="yes"/>
    <xsl:key name="k_cars" 
        match="/products/cars/car/attribs/attrib" 
        use="concat(../../brand,../../type,color)"/>

    <xsl:template match="/products">
        <ss:Table>
            <ss:Row>
                <!-- This is the header row -->
                <ss:Cell>
                    <ss:Data ss:Type="String">Brand / Model</ss:Data>
                </ss:Cell>
                <xsl:for-each select="colors/color">
                    <ss:Cell>
                        <ss:Data ss:Type="String">
                            <xsl:value-of select="id"/>/<xsl:value-of select="shortdesc"/>
                        </ss:Data>
                    </ss:Cell>
                </xsl:for-each>
            </ss:Row>

            <xsl:for-each select="cars/car">

                <ss:Row>
                    <ss:Cell>
                        <ss:Data ss:Type="String">
                            <xsl:value-of select="brand"/> <xsl:value-of select="type"/>
                        </ss:Data>
                    </ss:Cell>


                    <xsl:variable name="car" select="."/>

                    <xsl:for-each select="/products/colors/*">

                        <xsl:variable name="v_CarColor" 
                            select="key('k_cars',concat($car/brand,$car/type,id))"/>

                        <xsl:choose>

                            <xsl:when test="$v_CarColor">
                                <ss:Cell>
                                    <ss:Data ss:Type="String">
                                        <xsl:value-of select="$v_CarColor/price"/>
                                    </ss:Data>
                                </ss:Cell>
                            </xsl:when>

                            <xsl:otherwise>
                                <ss:Cell>
                                    <ss:Data ss:Type="String">-</ss:Data>
                                </ss:Cell>
                            </xsl:otherwise>

                        </xsl:choose>
                    </xsl:for-each>
                </ss:Row>
            </xsl:for-each>
        </ss:Table> 
    </xsl:template>

</xsl:stylesheet>
于 2011-08-05T20:36:14.187 に答える