すみません.xsl:evaluateの記述と例は誤りがありました.
> xsl:evaluateの@xpathからは、xsl:variableやxsl:paramを参照することができないとされています.
> 参照するには、xsl:evaluateの下位要素のxsl:with-paramを使います.
> 参照するには、xsl:evaluateの下位要素のxsl:with-paramを使います.
は、誤りです.@xpathの中からは、スコープ内のxsl:variableやxsl:paramを参照できます.ですからスタイルシートは、xsl:with-paramなしの以下で問題なく動作します.@xpathは"/data/product[@type= 'note']"となります.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="3.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs">
<xsl:output indent="yes"/>
<xsl:param name="prmAtrName" as="xs:string"/>
<xsl:param name="prmAtrValue" as="xs:string"/>
<xsl:template match="/">
<output>
<xsl:evaluate xpath="concat('/data/product[',$prmAtrName, ' = ''', $prmAtrValue,''']')"/>
</output>
</xsl:template>
</xsl:stylesheet>
<xsl:stylesheet version="3.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs">
<xsl:output indent="yes"/>
<xsl:param name="prmAtrName" as="xs:string"/>
<xsl:param name="prmAtrValue" as="xs:string"/>
<xsl:template match="/">
<output>
<xsl:evaluate xpath="concat('/data/product[',$prmAtrName, ' = ''', $prmAtrValue,''']')"/>
</output>
</xsl:template>
</xsl:stylesheet>
ではxsl:evaluateの子要素のxsl:with-paramはどう使うのでしょうか?これは@xpathがXPath式として評価されたとき変数として記述されたものとのインターフェースを取るのに使われます.
ですから、以下のようなxsl:evaluateの@xpathの記述の場合はxsl:with-paramが必要です.@xpathは"/data/product[@type= $prmAtrValue]"となり、$prmAtrValueを参照するからです.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="3.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
>
<xsl:output indent="yes"/>
<xsl:param name="prmAtrName" as="xs:string"/>
<xsl:param name="prmAtrValue" as="xs:string"/>
<xsl:template match="/">
<output>
<xsl:evaluate xpath="concat('/data/product[',$prmAtrName,' = $prmAtrValue]')">
<xsl:with-param name="prmAtrValue" as="xs:string" select="$prmAtrValue"/>
</xsl:evaluate>
</output>
</xsl:template>
</xsl:stylesheet>
<xsl:stylesheet version="3.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
>
<xsl:output indent="yes"/>
<xsl:param name="prmAtrName" as="xs:string"/>
<xsl:param name="prmAtrValue" as="xs:string"/>
<xsl:template match="/">
<output>
<xsl:evaluate xpath="concat('/data/product[',$prmAtrName,' = $prmAtrValue]')">
<xsl:with-param name="prmAtrValue" as="xs:string" select="$prmAtrValue"/>
</xsl:evaluate>
</output>
</xsl:template>
</xsl:stylesheet>
また、次のスタイルシートも誤りがありました.
>ところでSaxon9.3のインプリメントにはまだバグがあるようで、
>次のようにxsl:eveluateでXPathの動的エラーを発生させてみようと思いましたが、
>NPE(Null Pointer Exception)でこけてしまいました.
>次のようにxsl:eveluateでXPathの動的エラーを発生させてみようと思いましたが、
>NPE(Null Pointer Exception)でこけてしまいました.
現在のSaxon PE 9.3.0.4jにバグがあるのは確かです.これはとりあえずxsl:evaluateの@base-uriに影響のない適当な値をセットすれば回避できるとのこと.問題はxsl:evaluateの@xpathのXPath式は、そのときのカレントコンテキストで解釈されるということです.このため<xsl:template match="/">のコンテキストでxsl:evaluateが動くようにしてやらなければなりません.このためもう一個xsl:for-eachを追加する必要があります.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="3.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:err="http://www.w3.org/2005/xqt-errors"
exclude-result-prefixes="xs err"
>
<xsl:output indent="yes"/>
<xsl:param name="prmXPathFile" as="xs:string" select="'xpath.xml'"/>
<xsl:template match="/">
<xsl:variable name="currentNode" select="." as="document-node()"/>
<output>
<xsl:for-each select="doc($prmXPathFile)//xpath">
<xsl:variable name="xPath" select="string(.)" as="xs:string"/>
<xsl:message select="'XPath=',$xPath"/>
<xsl:try>
<xsl:for-each select="$currentNode">
<xsl:evaluate xpath="$xPath" base-uri="http://www.w3.org/1999/XSL/Transform"/>
</xsl:for-each>
<xsl:catch>
<xsl:message terminate="yes" select="'XPath evaluation failed: Error code:', $err:code, 'Reason:', $err:description"/>
</xsl:catch>
</xsl:try>
</xsl:for-each>
</output>
</xsl:template>
</xsl:stylesheet>
<xsl:stylesheet version="3.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:err="http://www.w3.org/2005/xqt-errors"
exclude-result-prefixes="xs err"
>
<xsl:output indent="yes"/>
<xsl:param name="prmXPathFile" as="xs:string" select="'xpath.xml'"/>
<xsl:template match="/">
<xsl:variable name="currentNode" select="." as="document-node()"/>
<output>
<xsl:for-each select="doc($prmXPathFile)//xpath">
<xsl:variable name="xPath" select="string(.)" as="xs:string"/>
<xsl:message select="'XPath=',$xPath"/>
<xsl:try>
<xsl:for-each select="$currentNode">
<xsl:evaluate xpath="$xPath" base-uri="http://www.w3.org/1999/XSL/Transform"/>
</xsl:for-each>
<xsl:catch>
<xsl:message terminate="yes" select="'XPath evaluation failed: Error code:', $err:code, 'Reason:', $err:description"/>
</xsl:catch>
</xsl:try>
</xsl:for-each>
</output>
</xsl:template>
</xsl:stylesheet>
実行結果は以下のようになります.xsl:try, xsl:catchが動作しているのを確認できます.
XPath= //data/product[string(@type) eq 'pencil']
XPath= //data/product[string(@type) eq 'note'][string(@unitPrice) eq '150']
XPath= //data/1/product[string(@type) eq 'other']
Warning: Required item type of first operand of '/' is node(); supplied value has item type xs:integer. The expression can succeed only if the supplied value is an empty sequence.
Warning: The only value that can pass type-checking is an empty sequence. Required item type of first operand of '/' is node(); supplied value has item type xs:integer
XPath evaluation failed: Error code: err:XPTY0019 Reason: Required item type of first operand of '/' is node(); supplied value has item type xs:integer
Processing terminated by xsl:message at line 21 in style.xsl
XPath= //data/product[string(@type) eq 'note'][string(@unitPrice) eq '150']
XPath= //data/1/product[string(@type) eq 'other']
Warning: Required item type of first operand of '/' is node(); supplied value has item type xs:integer. The expression can succeed only if the supplied value is an empty sequence.
Warning: The only value that can pass type-checking is an empty sequence. Required item type of first operand of '/' is node(); supplied value has item type xs:integer
XPath evaluation failed: Error code: err:XPTY0019 Reason: Required item type of first operand of '/' is node(); supplied value has item type xs:integer
Processing terminated by xsl:message at line 21 in style.xsl
以上 失礼しました.