0

背景:別のXSLT 2.0変換を実行するには、Webブラウザー内でXSLT 2.0を使用する必要があります。これは、XSLTプロセッサーのテストドライバーで使用されます。プロセッサ用のJavaScriptAPIを使用すると、変換を実行するための実行関数にパラメータとして渡されるリテラルコマンドオブジェクトを作成できます。

コマンドオブジェクトの構築はJavaScriptから非常に簡単ですが、XSLTからは、ユーザー定義のJavaScript関数を備えた組み込みのJavaScript拡張機能を使用して、XSLTデータをJavaScriptオブジェクトに変換する必要があります。XPath 2.0がアイテムのシーケンスで機能するという問題がありますが、シーケンスのシーケンスは許可されていません。私が現在使用しているアプローチは、変数cmdを宣言する次のXSLTスニペットに示されています。

JavaScriptオブジェクトを作成するためのXSLTコード

参考までに、同等のJavaScriptを以下に示します。

var cmd= {
            initialTemplate: initialTemplate,
            stylesheet:      stylesheet,
            source:          'uk-maps.xml',
            parameters:      {
                                            country:    'UK',
                                            city:       'Cheltenham',
                                            color:       [28, 329, 767]
                             }
};

JavaScriptにクロスするとき、XSLTプロセッサはシーケンスをJavaScriptオブジェクトの配列に変換します。ユーザー定義のJavaScript関数js:objectは配列を処理し、奇数アイテムのプロパティを作成し、対応する偶数アイテムからプロパティ値を割り当てます。js:object関数を再帰的に呼び出して、JavaScriptオブジェクトを新しいオブジェクトのプロパティに割り当てることができます。私の他の回避策は、ユーザー定義のjs:array関数です。これは、XPathシーケンスをJavaScriptオブジェクトにラップして、シーケンスアイテムとして埋め込むことができるようにします。js:object関数は、これらのjs:arrayオブジェクトを検出してアンラップする必要があります。

したがって、問題は次のとおりです。これは、XSLT 2.0内からJavaScriptリテラルオブジェクトを構築する1つの方法ですが、すべての人に適さない可能性のあるいくつかの回避策が含まれます。他にどのような方法を使用できますか?おそらく、XMLをリテラルJavaScriptオブジェクトに変換する既存のJavaScriptライブラリ関数を使用する必要がありますか?XSLT 3.0マップ(このプロセッサではまだ利用できません)は、より良いソリューションを提供しますか?提案されたJSON/XSLT互換性機能についてどのような進歩がありましたか?js:objectjs:arrayがプロセッサに組み込まれた拡張関数であるとしたら、もっと良いでしょうか?

4

2 に答える 2

1

これがそのような種類のタスクへの1つのアプローチです

次のXMLドキュメントがあるとします。

<t xmlns:js="js:aux">
 <initialTemplate>
   <js:var>initialTemplate</js:var>
 </initialTemplate>
 <stylesheet>
   <js:var>stylesheet</js:var>
 </stylesheet>
 <source>uk-maps.xml</source>
 <parameters>
  <js:object>
          <country>UK</country>
          <city>Cheltenham</city>
          <colours>
            <js:array>
                   <js:num>28</js:num>
                   <js:num>329</js:num>
                   <js:num>767</js:num>
           </js:array>
          </colours>
  </js:object>
 </parameters>
</t>

この変換

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

 <xsl:template match="/*">
  {
    <xsl:apply-templates/>
   }
 </xsl:template>

 <xsl:template match="*/*[not(self::js:*)]">
   <xsl:variable name="vNotLast" select="exists(following-sibling::*[1])"/>

         <xsl:sequence select="name(), ':&#9;'"/>
         <xsl:apply-templates/>

         <xsl:sequence select="','[$vNotLast], '&#xA;'"/>
 </xsl:template>

 <xsl:template match="*[not(self::js:*)]/text()">
  <xsl:sequence select='concat("&apos;", ., "&apos;")'/>
 </xsl:template>

 <xsl:template match="js:object">
  {
    <xsl:apply-templates/>
  }
 </xsl:template>

 <xsl:template match="js:array">
  [
    <xsl:apply-templates/>
  ]
 </xsl:template>

 <xsl:template match="js:array/*">
  <xsl:next-match/>

  <xsl:variable name="vNotLast" select="exists(following-sibling::*[1])"/>
  <xsl:sequence select="','[$vNotLast]"/>
 </xsl:template>
</xsl:stylesheet>

生成します

  {
    initialTemplate :   initialTemplate, 
 stylesheet :   stylesheet, 
 source :    'uk-maps.xml' , 
 parameters :   
  {
    country :    'UK' , 
 city :  'Cheltenham' , 
 colours :  
  [
    28,329,767
  ]


  }


   }

eval()次に、この結果をJavascript関数 にフィードする必要があります。

于 2012-05-05T18:06:45.713 に答える
0

私の現在の考えは、質問で概説されているXPath2.0で最初に元のソリューションを使用することです。次に、XPath 3.0マップがプロセッサでサポートされている場合、新しいマップコンストラクターを使用できるため、同等のコードは次のようになります。

<xsl:variable
name="cmd"
select="
map {
       'initialTemplate' := $initialTemplate;
       'stylesheet'      := $stylesheet;
       'source'          := 'uk-maps.xml';
       'parameters'      := map {
                                    'country'  := 'UK';
                                    'city'     := 'Cheltenham';
                                    'color'    := (28, 329, 767);

                                };
};
"/>

マップはシーケンスを値アイテムとして処理でき、他のマップを値アイテムとして含めることもできると想定しているため、JavaScript関数の呼び出しが唯一の非標準部分になります。

<xsl:variable name="result" as="document-node()" select="js:run($cmd)"/>
于 2012-05-06T11:31:31.303 に答える