2

単純な数式のXML表現に定数畳み込みを適用しようとしています。定数畳み込みは、定数(サブ)式をリテラル値に置き換えるプロセスです。定数畳み込みの一部は、2つのリテラル値に適用されるすべての2項演算を、計算されたリテラル結果に置き換えることです。つまり、次の式があるとします。

1+x+2*(3+1)

およびそのXML表現:

<addition>
   <addition>
      <value>1</value>
      <variable>x</variable>
   </addition>
   <multiplication>
      <value>2</value>
      <addition>
         <value>3</value>
         <value>1</value>
      </addition>
   </multiplication>
</addition>

交換できます

<addition>
   <value>3</value>
   <value>1</value>
</addition>

<value>4</value>

そしてその後、私たちは置き換えることができます

<multiplication>
   <value>2</value>
   <value>4</value>
</multiplication>

<value>8</value>

最終結果は次のようになります(さらに簡略化できますが、今のところこれで十分です)。

<addition>
   <addition>
      <value>1</value>
      <variable>x</variable>
   </addition>
   <value>8</value>
</addition>

XSLTスタイルシートの一部は次のようになります。

<xsl:template match="addition[count(value) = 2]">
   <value>
      <xsl:value-of select="value[1] + value[2]" />
   </value>
</xsl:template>

<xsl:template match="multiplication[count(value) = 2]">
   <value>
      <xsl:value-of select="value[1] * value[2]" />
   </value>
</xsl:template>

...

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

このテンプレートのアイデアは、両方のオペランド(子)が値要素であるすべての演算要素(加算、乗算など)を、計算された値を含む単一の値要素に再帰的に置き換えることです。ツリーの残りの部分(変数を含む操作)は同じに保たれます。

ただし、このスタイルシートは定数畳み込みを1回だけ適用し、最も深い二項演算要素をリテラル値に置き換えるだけです。このスタイルシートを機能させる唯一の方法は、入力ドキュメントと出力ドキュメントが同じになるまで、最後の変換の出力を変換し続けることです。私はXSLTを初めて使用するので、これを行うためのより自然な方法があるはずです。

4

1 に答える 1

2

この変換

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

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

 <xsl:template match="addition[not(descendant::variable)]">
     <xsl:variable name="vArg1">
       <xsl:apply-templates select="*[1]"/>
     </xsl:variable>
     <xsl:variable name="vArg2">
       <xsl:apply-templates select="*[2]"/>
     </xsl:variable>

     <value>
       <xsl:value-of select="$vArg1 + $vArg2"/>
  </value>
 </xsl:template>

 <xsl:template match="multiplication[not(descendant::variable)]">
     <xsl:variable name="vArg1">
       <xsl:apply-templates select="*[1]"/>
     </xsl:variable>
     <xsl:variable name="vArg2">
       <xsl:apply-templates select="*[2]"/>
     </xsl:variable>

     <value>
       <xsl:value-of select="$vArg1 * $vArg2"/>
  </value>
 </xsl:template>
</xsl:stylesheet>

提供されたXMLドキュメントに適用した場合

<addition>
   <addition>
      <value>1</value>
      <variable>x</variable>
   </addition>
   <multiplication>
      <value>2</value>
      <addition>
         <value>3</value>
         <value>1</value>
      </addition>
   </multiplication>
</addition>

必要な正しい結果を生成します

<addition>
   <addition>
      <value>1</value>
      <variable>x</variable>
   </addition>
   <value>8</value>
</addition>

説明:テンプレートの適切な使用、xsl:apply-templatesおよびxsl:variable

于 2011-12-28T15:59:56.983 に答える