1

私は基本的に次のような XML 入力構造を持っています。

...
<box type="rectangle" class="someOriginalClass">
    <background bgtype="solid" />
    <animation order="3" />
    ... children
</box>

そしてそれをに変換したい

<div class="someOriginalClass rectangle solid animated order3">
    ...children
</div>

背景もアニメーションもそこにある必要はないことに注意してください。これは縮小された例であり、より多くの属性を持つ、これらのようなプロパティがさらに存在する可能性があることを意味します。同様に、アニメーションと背景は別の場所で再利用されます。

これまでの私のXSLTコードは次のとおりです。

<xsl:template match="box">
    <div class="{@someOldClass} {@type}">
        <xsl:apply-templates select="./*" />
    </div>
</xsl:template>

<xsl:template match="background">
    <xsl:attribute name="class">
      <xsl:value-of select="@bgtype"/>
    </xsl:attribute>
</xsl:template>

<xsl:template match="animation">
    <xsl:attribute name="class">
      animated order<xsl:value-of select="@order"/>
    </xsl:attribute>
</xsl:template>

このコードの問題は、各テンプレートが class 属性を完全にオーバーライドし、既に含まれているクラスを破棄することです。

これを解決するために、私は試しました:

a) 古いクラスの書き換え => value-of は入力 XML クラス (someOldClass) のみを取得します。

<xsl:template match="animation">
    <xsl:attribute name="class">
      <xsl:value-of select="../@class"/>
      animated order<xsl:value-of select="@order"/>
    </xsl:attribute>
</xsl:template>

b) 代わりに、params を使用してテンプレート間で変更を渡す => 1 回のみ、一方向

<xsl:template match="box">
    <div class="{@someOldClass} {@type}">
        <xsl:apply-templates select="./*">
            <xsl:with-param name="class" select="concat(@someOldClass,' ',@type)"/>
        </xml:apply-templates>
    </div>
</xsl:template>

<xsl:template match="animation">
    <xsl:param name="class"/>
    <xsl:attribute name="class">
      <xsl:value-of select="$class"/>
      animated order<xsl:value-of select="@order"/>
    </xsl:attribute>
</xsl:template>

おわかりのように、最小限の冗長性で、任意の数のクラスの更新に対応できるソリューションがありません。ところで、私は XSLT の初心者なので、まだ出会っていない予定の機能があるかもしれません。

何か案は?

4

1 に答える 1

0

私はこれを以前に使用したことがあります。XML がどのように見えるかはわかりませんが、これは正しい道を歩むのに役立つかもしれません。

<xsl:template match="box">
<xsl:param name="boxType" />
<li>
    <xsl:variable name="boxClass">
        <xsl:value-of select="$boxType"/>
        <xsl:if test="@class1 = 1"> class1</xsl:if>
        <xsl:if test="@class2 = 1"> class2</xsl:if>
        <xsl:if test="@class3 = 1"> class3</xsl:if>
        <xsl:if test="@class4 = 1"> class4</xsl:if>
        <xsl:if test="@last = 1"> lnLast</xsl:if>
    </xsl:variable>
    <xsl:attribute name="class">
        <xsl:value-of select="$boxClass"/>
    </xsl:attribute>
</li>
</xsl:template>
于 2012-10-01T17:20:50.587 に答える