5

別のスレッドに答える(stackoverflow:cssカラースキームの生成を参照)私は以下の問題にぶつかりました。そこでは、異なるxslエンジンが、結果ツリーフラグメントをノードセットに変換する際に異なるアプローチを必要とするようです。

問題を単純化するために(ただし、この背後にある完全なストーリーについては上記のリンクを参照してください)、色の値のリストを含むインラインツリーが必要です。これはXpath式で使用する必要があるため、MSXML xx xslエンジン専用のノードセットを作成する必要がありました(XML Spy組み込みでは、rtfとして構築された変数を含むXpath式の解釈に問題がありませんでした)。
さらに別のスレッドスタックオーバーフロー:automating-exsltnode-setが私を助けてくれました。結果のノードセットは、入力XMLから新しい変数rtfを作成する際に使用されます。
繰り返しになりますが、MSXMLはXpath式で新しい変数が使用されると文句を言うので、node-set関数を使用してそこからノードセットを作成しました。
これまでのところ良好であり、MSXMLxxはエラーを発生しなくなりました。
しかし、XMLSpyビルトインまたはSaxon9heで同じものを実行すると、別のエラーが発生します。ノードセット関数が不明であるようです。

Cannot find a matching 1-argument function named {urn:schemas-microsoft-com:xslt}node-set() in variable colorList

この特定の例では、この2段階のアプローチは必要ありませんが、前述したように、物事を単純化したことに注意してください。すべてのxslエンジンで機能するXSLT1.0変換を作成する方法を知りたいだけです。

私が使用したXSLT:

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet
    version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:std="http://whatever"
    xmlns:exslt="urn:schemas-microsoft-com:xslt"
    exclude-result-prefixes="std exslt">

    <xsl:output method="xml" indent="yes"/>

    <std:colors>
        <color>#0000FF</color>
        <color>#FF0000</color>
    </std:colors>

    <xsl:variable name="colors" select="document('')/*/std:colors"/>

    <xsl:variable name="std:colorList">
        <xsl:for-each select="//testid">
            <xsl:variable name="pos" select="position() mod 2"/>
            <xsl:element name="color">
                <xsl:attribute name="testid"><xsl:value-of select="."/></xsl:attribute>
                <xsl:value-of select="$colors/color[$pos + 1]"/>
            </xsl:element>
        </xsl:for-each>
    </xsl:variable>

    <xsl:variable name="colorList" select="exslt:node-set($std:colorList)"/>

    <xsl:template match="/">
        <output>
            <xsl:copy-of select="$colorList/color"/>
        </output>
   </xsl:template>

</xsl:stylesheet>

入力ファイル:

<?xml version="1.0" standalone="yes"?>
<NewDataSet>
  <defects>
    <testid>111</testid>
  </defects>
  <defects>
    <testid>999</testid>
  </defects>
</NewDataSet>

MSXML 3.0 / 4.0 /6.0の結果:

<?xml version="1.0" encoding="UTF-16"?>
<output>
<color testid="111">#FF0000</color>
<color testid="999">#0000FF</color>
</output>

Saxon9heの結果:

Cannot find a matching 1-argument function named {urn:schemas-microsoft-com:xslt}node-set()
in variable colorList

結果として、XMLSpy組み込みxslエンジンになります。

Error in XPath expression
Unknown function - Name and number of arguments do not match any function signature in the static context - 'urn:schemas-microsoft-com:xslt:node-set'
4

5 に答える 5

7

MSXML以外のプロセッサの場合は、exslt:node-set()関数を使用します。(http://www.exslt.org/)。(exsltプレフィックスをMicrosoftバージョンの関数にバインドするのは少し奇妙です-しばらく混乱していました!)

function-available()を使用して、使用可能な関数をテストできます。

<xsl:choose>
  <xsl:when test="function-available('exslt:node-set')"...
  <xsl:when test="function-available('msxsl:node-set')"...

Saxon-HEおよびその他のXSLT2.0プロセッサの場合、これらの関数は必要ないため、次を使用してください。

<xsl:when test="xsl:version='2.0'">
于 2012-03-23T10:57:29.720 に答える
5

する必要を避けるために

 <xsl:choose>
 <xsl:when test="function-available('exslt:node-set')"...

これが必要になるたびに、xslt2エンジン(xsl:functionを使用)およびmsxml(msxsl:scriptを使用)のexsltノードセットを定義してから、ドキュメントの残りの部分でexslt:node-set関数を使用できます。

http://dpcarlisle.blogspot.co.uk/2007/05/exslt-node-set-function.html

msxmlおよびxslt2エンジンに対してそれを定義する方法を示します。xsl:スタイルシートを含めることができます。

<xsl:stylesheet version="2.0"
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        xmlns:exslt="http://exslt.org/common"
        >

<xsl:function name="exslt:node-set">
  <xsl:param name="rtf"/>
  <xsl:sequence select="$rtf"/>
</xsl:function>

<xsl:stylesheet>

XSLT1の上位互換性ルールは、これを含めても安全であることを意味します。XSLT1エンジンはこれを無視します。

于 2012-03-23T12:21:40.377 に答える
2

MicrosoftのXsltCompiledTransform.NETXSLTプロセッサは、exslt:node-set()をサポートしています。

MSXMLの場合、EXSLT関数のサブセットの独自の実装を使用できます(MSXMLの場合)。詳細な説明とダウンロードへのリンクは、次の場所にあります。

http://www.xml.com/pub/a/2003/08/06/exslt.html

于 2012-03-23T13:05:10.907 に答える
1

Saxon9はXSLT2.0プロセッサであり、XSLT 2.0の主な改善点の1つは、ノードセットと結果ツリーフラグメントの区別がなくなり、強制する必要がないため、拡張機能がまったく必要ないことです。もうどんな強制も。したがって、XSLT 2.0プロセッサを対象とするスタイルシートでは、そのような拡張機能を使用する試みをすべてドロップするだけで、スタイルシートは機能します。XSLT 1.0プロセッサと2.0プロセッサの両方で同じスタイルシートを実行したい場合は、問題が発生しますが、簡単な解決策はないと思います。プロセッサと拡張機能の可用性を区別するには、 http://www.w3.org/TR/xslt#function-function-availableとsystem-propertyを利用する必要があります。

于 2012-03-23T10:56:33.520 に答える
-1

さて、あなたはチェックなしでそれを簡単に行うことができます。ここで説明されているパターンに従ってください:http: //dpcarlisle.blogspot.co.uk/2007/05/exslt-node-set-function.html

<xsl:stylesheet
  version="1.0" 
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:exslt="http://exslt.org/common"
  xmlns:msxsl="urn:schemas-microsoft-com:xslt"
  exclude-result-prefixes="exslt msxsl">


<msxsl:script language="JScript" implements-prefix="exslt">
 this['node-set'] =  function (x) {
  return x;
  }
</msxsl:script>


<xsl:variable name="x">
  <y/>
</xsl:variable>

<xsl:template match="x">
  <html>
    <head><title>test exslt node set</title></head>
    <body>
      <xsl:apply-templates select="exslt:node-set($x)/*"/>
    </body>
  </html>
</xsl:template>

<xsl:template match="y">
  <p>node set!</p>
</xsl:template>

</xsl:stylesheet>

FF、Chrome、IE7+で間違いなく動作します

于 2013-08-29T09:32:50.040 に答える