0

WiX の heat ユーティリティによって生成された WXS ファイルがあります。別の XML ファイルの内容に基づいて特定のコンポーネントを自動的に除外するように (既存の) excludes.xslt ファイルで変更しようとしています (これをparts.xml呼びます)。xslt ファイルは現在、一部のコンポーネント/ファイル/ディレクトリをインストーラーから削除するために使用されていますが、比較的静的なリストです。

ただし、今のところ、私の主な関心事は、パラメーターから正しいパスを読み込んで保存し、その内容を変数に保存することです。

これは変換がどのように適用されるかです (WiX がファイル「before.wxs」への熱の収集を終了したら):

msxsl.exe "before.wxs" "exclusions.xslt" -o "after.wxs" srcroot="$(SrcRoot)"

ユーザーのマシンでparts.xmlを検索するために使用される XSLT ファイル内のパラメーターとして、srcroot を渡しました。

コマンド ラインからパラメータを取得し、すべてのバック スラッシュをスラッシュに置き換えるには:

<!-- Adapted from http://stackoverflow.com/a/30153713/5605122 and http://geekswithblogs.net/Erik/archive/2008/04/01/120915.aspx-->
<xsl:param name="srcroot" />
<xsl:variable name="filename">
    <xsl:call-template name="string-replace-all">
        <xsl:with-param name="text" select="concat('file://', $srcroot, '/foo/parts.xml')" />
        <xsl:with-param name="replace" select='\\' />
        <xsl:with-param name="by" select='/' />
    </xsl:call-template>
</xsl:variable>
<xsl:variable name="myparts" select="document($filename)" />

ここから取得した string-replace-allは次のとおりです。

<!-- XSL 1.0 string-replace-all, taken from: http://geekswithblogs.net/Erik/archive/2008/04/01/120915.aspx -->
<xsl:template name="string-replace-all">
    <xsl:param name="text" />
    <xsl:param name="replace" />
    <xsl:param name="by" />
    <xsl:choose>
        <xsl:when test="contains($text, $replace)">
            <xsl:value-of select="substring-before($text,$replace)" />
            <xsl:value-of select="$by" />
            <xsl:call-template name="string-replace-all">
                <xsl:with-param name="text"
                select="substring-after($text,$replace)" />
                <xsl:with-param name="replace" select="$replace" />
                <xsl:with-param name="by" select="$by" />
            </xsl:call-template>
        </xsl:when>
        <xsl:otherwise>
            <xsl:value-of select="$text" />
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>

役に立たないエラーが表示されます。

コード: 0x80004005 クエリ文字列に予期しない文字が含まれています。

しかし、投稿したコード スニペットだけを削除すると、エラーはなくなります。これをデバッグして何が起こっているのかを理解する方法はわかりませんが、調べてみると、単なるタイプミスや構文エラーではなく、何が起こるべきかについて根本的な誤解をしていると思います。

最終的には、parts.xml の内容を「myparts」に格納したいと考えています。ここで何が欠けていますか?

ありがとう!

4

1 に答える 1

0

文字列リテラルを一重引用符で囲むだけでよいことがわかりました (バックスラッシュをエスケープする必要はありませんでした)。また、私の srcroot には末尾のバックスラッシュがあるため、ここでは最初から省略しました。更新されたコードは次のとおりです。

<!-- Adapted from http://stackoverflow.com/a/30153713/5605122 and http://geekswithblogs.net/Erik/archive/2008/04/01/120915.aspx-->
<xsl:param name="srcroot" />
<xsl:variable name="filename">
    <xsl:call-template name="string-replace-all">
        <xsl:with-param name="text" select="concat($srcroot, 'foo/parts.xml')" />
        <xsl:with-param name="replace" select="'\'" />
        <xsl:with-param name="by" select="'/'" />
    </xsl:call-template>
</xsl:variable>

それをテストする方法を理解する問題については、次のようにしてファイルが存在するかどうかを最終的に確認するようになりました。

msxsl を使用しているので、fileExists 関数の拡張子を使用することにしました。

<!-- Adapted from https://www.stylusstudio.com/SSDN/default.asp?action=9&read=2993&fid=48 -->
<msxsl:script language="JScript" implements-prefix="user">
<![CDATA[
fso = new ActiveXObject("Scripting.FileSystemObject");
function fileExists(filename){
return fso.FileExists(filename);
}

// With .NET XSLT processor we need to use the Framework API
//function fileExists(filename){
//return System.IO.File.Exists(filename); 
//} 

]]>
</msxsl:script>

テンプレート内で、次のチェックを行いました。

<xsl:if test="not( function-available('user:fileExists') )">
        <xsl:message terminate="yes">
            <xsl:text>Required facilities are not available.</xsl:text>
        </xsl:message>
</xsl:if>

そして、それが合格した場合、私は次のことを行いました:

<xsl:choose>
    <xsl:when test="user:fileExists(string($filename))">
        <xsl:message terminate="yes">
            <xsl:text>File found! Here:</xsl:text>
            <xsl:copy-of select="$filename"/>
        </xsl:message>
    </xsl:when>
    <xsl:otherwise>
        <xsl:message terminate="yes">
            <xsl:text>File cannot be found:</xsl:text>
            <xsl:copy-of select="$filename"/>
        </xsl:message>
    </xsl:otherwise>
</xsl:choose>

何らかの理由で terminate="yes" を設定しない限り、メッセージはコンソールに出力されなかったので、これによりビルドが停止し、削除する必要がありますが、これをデバッグしてパラメーターが正常に受信されたことを確認するのに役立ちましたXSLT ファイルによって、そのパスにファイルが存在するかどうかを確認できます。

于 2016-01-21T19:49:03.657 に答える