0

入力ファイルには、変数とタイプの2つのタグがあります。

<variable baseType="int" name="X">
</variable>

<type baseType="structure" name="Y">
    <variableInstance name="X" />
</type>

そして、次の出力ファイルを生成する必要があります。

<Item name="Y">
    <Field name="X" type="Long" />
</Item>

したがって、概念的には、ここでの私のアプローチは、タイプタグをアイテムタグに変換し、変数インスタンスをフィールドに変換することでした。それはうまく機能しています:

<xsl:for-each select="type[@baseType='structure']">
    <Item>
        <xsl:attribute name="name"><xsl:value-of select="@name" /></xsl:attribute>
        <xsl:for-each select="variableInstance">
            <Field>
                <xsl:attribute name="name"><xsl:value-of select="@name" /></xsl:attribute>
                <xsl:attribute name="type">**THIS IS WHERE I'M STUCK**</xsl:attribute>
            </Field>
        </xsl:for-each>
    </Item>
</xsl:for-each>

私が立ち往生している問題は次のとおりです。

  1. variableInstance / Fieldタグを変数タグと名前で一致させる方法がわからないため、baseTypeにアクセスできます。
  2. 1ができるようになったら、「int」を「Long」にマップする必要があります。

前もって感謝します!

4

2 に答える 2

1

問題1。

最初の問題については、キーを使用できます。

<xsl:key name="variable-key" match="//variable" use="@name" />

そのキーは、名前を使用して、ドキュメント内のすべての可変要素にインデックスを付けます。したがって、次の XPath 式を使用して、これらの要素にアクセスできます。

key('variable-key', 'X')

このアプローチは、可変要素が多い場合に効率的です。

注: 各変数に独自のスコープがある場合 (つまり、ドキュメントの別の部分に表示されないローカル変数がある場合)、このアプローチは有効ではありません。その場合、このアプローチを変更する必要があります。

問題2。

属性のマッピングには、次のようなテンプレートを使用できます。

    <xsl:template match="@baseType[. = 'int']">
        <xsl:attribute name="baseType">
            <xsl:value-of select="'Long'" />
        </xsl:attribute>
    </xsl:template>

この変換の意味は、baseType 属性を int 値と一致させるたびに、Long 値に置き換える必要があるということです。

この変換は、ドキュメント内の @baseType 属性ごとに行われます。


説明した戦略を使用すると、解決策は次のようになります。

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

    <xsl:output method="xml" indent="yes" />

    <!-- Index all variable elements in the document by name -->
    <xsl:key name="variable-key"
             match="//variable"
             use="@name" />

    <!-- Just for demo -->
    <xsl:template match="text()" />

    <!-- Identity template: copy attributes by default -->
    <xsl:template match="@*">
        <xsl:copy>
            <xsl:value-of select="." />
        </xsl:copy>
    </xsl:template>

    <!-- Match the structure type -->
    <xsl:template match="type[@baseType='structure']">
        <Item>
            <xsl:apply-templates select="*|@*" />
        </Item>
    </xsl:template>

    <!-- Match the variable instance -->
    <xsl:template match="variableInstance">
        <Field>
            <!-- Use the key to find the variable with the current name -->
            <xsl:apply-templates select="@*|key('variable-key', @name)/@baseType" />
        </Field>
    </xsl:template>

   <!-- Ignore attributes with baseType = 'structure' -->
    <xsl:template match="@baseType[. = 'structure']" />

    <!-- Change all baseType attributes with long values to an attribute
        with the same name but with an int value  -->
    <xsl:template match="@baseType[. = 'int']">
        <xsl:attribute name="baseType">
            <xsl:value-of select="'Long'" />
        </xsl:attribute>
    </xsl:template>

</xsl:stylesheet>

このコードは、次の XML ドキュメントを変換します。

<!-- The code element is present just for demo -->
<code>
    <variable baseType="int" name="X" />
    <type baseType="structure" name="Y">
        <variableInstance name="X" />
    </type>
</code>

の中へ

<Item name="Y">
    <Field baseType="Long" name="X"/>
</Item>
于 2013-02-25T15:40:19.960 に答える
0

大木ポイント1のxsltcakeスライスまたはテンプレートを使用したソリューションがあります。ポイント2については、パブロ・ポゾが回答で使用したものと同様のテンプレートを使用するでしょう

于 2013-02-25T16:05:40.817 に答える