2

あるメッセージから別のメッセージに変換する単純な xslt を作成したとします。逆を自動的に生成する方法はありますか?

元の XSLT

 <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
      <xsl:template match="/">
      <hello>
         <xsl:for-each select="/hello/greeting">        
        <H1>
              <xsl:value-of select="."/>
        </H1>
       </xsl:for-each>
       </hello>
      </xsl:template>
    </xsl:stylesheet>

希望する XSLT

    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:template match="/">
   <hello>
   <xsl:for-each select="/hello/H1">        
      <greeting>
          <xsl:value-of select="."/>
      </greeting>
   </xsl:for-each>
   </hello>
  </xsl:template>
</xsl:stylesheet>
4

3 に答える 3

2

いいえ、XSLT を元に戻す一般的な方法はありません。実際、XSLT の大部分は元に戻せません。ただし、パラメーター値を変更することで、順方向または逆方向に実行できるように上記の例を設計することは可能です。

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:exslt="http://exslt.org/common">
  <xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
  <xsl:param name="direction" select="'forward'" />

  <xsl:variable name="mappingNF">
    <map from="greeting" to="H1" />
    <map from="pleasantry" to="H2" />
  </xsl:variable>
  <xsl:variable name="mapping" select="exslt:node-set($mappingNF)" />

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

  <xsl:template match="*" mode="copy">
    <xsl:call-template name="Copy" />
  </xsl:template>

  <xsl:template match="*">
    <xsl:variable name="mappingItem"
                  select="$mapping/*[$direction = 'forward' and @from = local-name(current()) or
                                 $direction = 'reverse' and @to = local-name(current())]" />

    <xsl:apply-templates select="current()[$mappingItem]" mode="rename">
      <xsl:with-param name="mappingItem" select="$mappingItem" />
    </xsl:apply-templates>
    <xsl:apply-templates select="current()[not($mappingItem)]" mode="copy" />
  </xsl:template>

  <xsl:template match="*" mode="rename">
    <xsl:param name="mappingItem" />

    <xsl:element name="{$mappingItem/@to[$direction = 'forward'] |
                        $mappingItem/@from[$direction = 'reverse']}">
      <xsl:apply-templates select ="@* | node()" />
    </xsl:element>
  </xsl:template>
</xsl:stylesheet>

mappingNFはノード名間の対応を示し、これは必要な数の で拡張できますmapdirectionパラメータの値を「forward」と「reverse」の間で変更することにより、変換の方向を前後に切り替えることができます。

于 2013-04-24T07:43:26.103 に答える
1

おそらく、コンピュータ サイエンスの学生が、可逆的な XSLT 変換のクラスがあるかどうかを確認するための興味深い演習があるでしょう。これはもちろん、変換が無損失でなければならないことを意味します。最も明白な候補は、要素の名前を変更する以外に何もしない変換ですが、それでもスタイルシートが 2 つの異なる入力名を同じ出力名。そのため、最終的にはかなり小さなセットになると思います。

実際には、HTML ヘッダーなどの冗長な情報を追加する変換や、おそらく 2 つの入力要素が同じ出力要素にマップされるが異なる属性を持つ変換 (たとえば、div class="X" where X入力要素名を再構成できるようにします)。

于 2013-04-24T08:25:38.297 に答える
0

逆方向に自動的に生成する方法はないと思います

ただし、テンプレートが同じである場合、現在の XSL のほとんどのものを再利用できます。

あなたの例では、それは

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:template match="/">
  <hello>
     <xsl:for-each select="/hello/H1 | /hello/greeting">       
    <H1>
          <xsl:value-of select="."/>
    </H1>
   </xsl:for-each>
   </hello>
  </xsl:template>
</xsl:stylesheet> 
于 2013-04-24T06:00:48.760 に答える