2011-12-16 8 views
3

私はこのようなXSLT持っている:document()がロードされているfooDocument.xml内のノードと一致する2番目のテンプレートでは、XSLT:XPathのコンテキストおよび文書()

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:transform version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
         xmlns:xalan="http://xml.apache.org/xalan"> 

    <xsl:variable name="fooDocument" select="document('fooDocument.xml')"/> 

    <xsl:template match="/"> 
    <xsl:apply-templates select="$fooDocument//*"/> 
    </xsl:template> 

    <xsl:template match="nodeInFooDocument"> 
    <xsl:variable name="valueFromSource" select="//someSourceElement"/> 
    </xsl:template> 
</xsl:transform> 

を、私はXML内のノードにアクセスしたいです変換が実行されるソース。明らかに、XPathはfooDocumentのコンテキストでこのパスを実行するので、これは//someSourceElementでは機能しません。

心に来る最初の回避策はこれです:

... 
<!-- global variable --> 
<xsl:variable name="root" select="/"/> 

... 
<!-- in the template --> 
<xsl:variable name="valueFromSource" select="$root//someSourceElement"/> 

... 

しかし、実際には、私の変数は次のように選択されているので、私は、この回避策を使用することはできません。

<xsl:variable name="valueFromSource" select="xalan:evaluate($someXPathString)"/> 

$someXPathString

がに細工されていませんXSLTファイルですが、fooDocumentからロードされます(上で使用されているような絶対パスを含みます)。それでも、私は何とかXPathコンテキストをXMLソースに戻す必要があります。

<xsl:for-each select="$root[1]"> 
    <xsl:variable name="valueFromSource" select="xalan:evaluate($someXPathString)"/> 
</xsl:for-each> 

(役に立たない)for-eachループは、このようXPathは正しく評価し、バックメインXMLソースにコンテキストを変更します。私が見つけ非常ハック回避策は、このです。しかし明らかに、これは容認できる解決策ではありません。

これを行う方法はありますか、または誰かがより良い回避策を提案できますか?

答えて

3

コンテキスト文書を変更するためのfor-each select="$root"での試みが受け入れられないと思うとしても、これは正しいアプローチです。だから、それを使用し、他の方法はありません。

+1

私はのために、各コンテキスト文書(やや非直観的な場合)を変更するための細かい方法であることに同意、しかし確実にマーティンは、あなたは他の方法がないことを意味するものではありません。例えば。 'apply-templates select =" $ root "'(モードの有無にかかわらず)文脈文書を設定するでしょうか? – LarsH

+0

私は文脈文書を変更する他の実現可能な方法を見つけませんでした。 – flyx

2

一連のグローバル変数を使用して$ someXPathStringを構築する計算をすべて行うことを検討しましたか?

<xsl:variable name="fooDocument" select="document('fooDocument.xml')"/> 

<xsl:variable name="temp1" 
    .. some computation using fooDocument .. 
</xsl:variable> 

<xsl:variable name="temp2" 
    .. some computation using temp1 .. 
</xsl:variable> 

<xsl:variable name="someXPathString" 
    .. some computation using temp2 .. 
</xsl:variable> 

<xsl:variable name="root" select="xalan:evaluate($someXPathString)"/> 
+0

これは、fooDocumentのすべての内容をグローバル変数にコピーし、その上にxalan:nodeset()を使用することを選択した場合に機能します。 fooDocumentには任意の長さのシーケンスが含まれているため、プリミティブ値を保持する固定数のグローバル変数に分割することはできません。読みやすくするために、これは間違いなくオプションです。編集:2番目の考えでは、このグローバル変数に 'apply-templates'を使うと、私のコンテキストはまだXMLソースにはなく、xalan:nodeset()呼び出しの結果を含む変数にあります。 – flyx

関連する問題