2012-05-05 14 views
0

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

コマンドオブジェクトをビルドするのはJavaScriptからはかなり簡単ですが、XSLTからは、ユーザー定義のJavaScript関数を組み込んだJavaScript拡張を使用して、XSLTデータをJavaScriptオブジェクトに変換する必要があります。 XPath 2.0は一連の項目で動作するという問題がありますが、シーケンスのシーケンスは許可されていません。私は現在、変数を宣言し、次のXSLTのスニペットに示されている使用しているアプローチ、CMD

XSLT code to create a JavaScript object

同等の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は、配列を処理し、奇数項目のプロパティと対応する偶数項目のasignsプロパティ値を作成します。 js:object関数を再帰的に呼び出すと、新しいオブジェクトのプロパティにJavaScriptオブジェクトを割り当てることができます。私の他の回避策は、ユーザー定義のjs:array関数です。これは、JavaScriptオブジェクトにXPathシーケンスをラップし、シーケンスアイテムとして埋め込むことができます。 js:object関数は、これらのjs:arrayオブジェクトを検出して展開する必要があります。

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

+0

この問題のAPIの仕様にこだわるしないでください - それはちょうどXSLTの一例として、前方に置かれました/ JSONの相互運用性 - 理想的ではない可能性があります。 – pgfearo

+0

これはすべて純粋なXSLTで行うことができます - どうしてあなたは拡張機能を使うべきだと決めましたか? –

+0

@Dimitre純粋なXSLTのリテラルオブジェクトである配列とプロパティ値を持つJavaScriptオブジェクトを作成するにはどうすればよいですか?あなたは簡単な例を挙げることができますか?何か明白なものがありませんか? – pgfearo

答えて

1

は、タスクのような種類の一つのアプローチは以下のとおりです。この変換

<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> 

::次のXML文書を考えると

<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 
    ] 


    } 


    } 

この結果は、JavaScriptのeval()関数に渡す必要があります。

+0

+1私はあなたが提案するソリューションの移植性が気に入っています。必要な構文解析を行うには、eval()呼び出し以上のものが必要ですが、必要な場合は必要な字句解析XMLを持つjs:node要素もあります。私はこれが一般的なパターンであり、「標準」スキーマが既に使用されているという答えがあるかどうかを確認するのを待っています。 – pgfearo

+0

この答えでは、* initialTemplate *および* stylesheet *への未解決の参照があるため、変換から生成された出力はeval()関数内では機能しません。 – pgfearo

+0

@pgfearo:はい、これらは質問には載っていません。私の推測では、この変換が行われる前に、参照された変数の値がJSONに変換されることがあります。 –

0

私の現在の考えは、質問で概説されたXPath 2.0で元のソリューションを最初に使用することです。次に、XPath 3。0マップは新しいmap constructorを使用することができるプロセッサによってサポートされているので、同等のコードは次のようになります。私はマップが値項目としてシーケンスを扱うことができると仮定してい

<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)"/> 
関連する問題