1

次のような .wxs ファイルがあります。

<?xml version="1.0" encoding="utf-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
    <Fragment>
        <Directory>
            <Directory Id="d1">
                <Component Id="c1" ...>
                    <File Id="f1" KeyPath="yes" ... />
                </Component>
                <Component Id="c2" ...>
                    <File Id="f2" KeyPath="yes" ... />
                </Component>
                <Component Id="c3" ...>
                    <File Id="f3" KeyPath="yes" ... />
                </Component>
            </Directory>
            <Directory>
                <Component>
                ...
            </Directory>
            ...
        </Directory>
    </Fragment>
    <Fragment>
        <ComponentGroup Id="cg1">
            <ComponentRef Id="c1" />
            <ComponentRef Id="c2" />
            <ComponentRef Id="c3" />
            ...
        </ComponentGroup>
    </Fragment>
</Wix>

上記のコンポーネントを「マージ」したい、つまり、ファイル f2、f3 をコンポーネント c1 に移動し、コンポーネント c2、c3 と c2、c3 のコンポーネント参照を削除したい。私の実際のソース コードには、コンポーネントを含むさらに多くのディレクトリがあります。私の意図は、コンポーネントの数を減らすことです。つまり、次のようなパターンの場合

<Directory>
    <Component>
        <File KeyPath="yes" />
    </Component>
    <Component>
        <File KeyPath="yes" />
    </Component>
    ...
    <Component>
        <File KeyPath="yes" />
    </Component>
</Directory>

次のような多くのファイルを含む1つのコンポーネント(おそらく最初のコンポーネント)にそれらを減らしたい:

<Directory>
    <Component>
        <File KeyPath="yes" />
        <File />
        ...
        <File />
    </Component>
</Directory>

1 つのコンポーネントに多くのファイルを含めることはお勧めできませんが、アンインストール時間を短縮するためにそうしたいと考えています。現在、私のインストーラーのアンインストールにはかなりの時間がかかります。これは、コンポーネントが多すぎる (20,000 程度) ためだと思います。

どんな助けでも大歓迎です。ありがとうございました。

4

2 に答える 2

1

following-siblingそれを達成する最も簡単な方法は、軸を使用することだと思います:

スタイルシート

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:wi="http://schemas.microsoft.com/wix/2006/wi">
  <xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes"/>
  <xsl:strip-space elements="*"/>

  <!-- Identity transform -->
  <xsl:template match="@* | node()">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="wi:Directory">
    <xsl:copy>
      <!-- Only apply the first <Component> element -->
      <xsl:apply-templates select="wi:Component[1]"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="wi:Component[1]">
    <xsl:copy>
      <!-- Apply attributes -->
      <xsl:apply-templates select="@*"/>
      <!-- Apply the <File> element in this <Component> element -->
      <xsl:apply-templates select="wi:File"/>
      <!-- Apply the <File> elements in all following <Component> siblings -->
      <xsl:apply-templates select="following-sibling::wi:Component/wi:File"/>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

入力

<?xml version="1.0" encoding="utf-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
  <Fragment>
    <Directory Id="d1">
      <Component Id="c1">
        <File Id="f1" KeyPath="yes"/>
      </Component>
      <Component Id="c2">
        <File Id="f2" KeyPath="yes"/>
      </Component>
      <Component Id="c3">
        <File Id="f3" KeyPath="yes"/>
      </Component>
    </Directory>
  </Fragment>
  <Fragment>
    <ComponentGroup Id="cg1">
      <ComponentRef Id="c1"/>
      <ComponentRef Id="c2"/>
      <ComponentRef Id="c3"/>
    </ComponentGroup>
  </Fragment>
</Wix>

出力

<?xml version="1.0" encoding="utf-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
  <Fragment>
    <Directory>
      <Component Id="c1">
        <File Id="f1" KeyPath="yes"/>
        <File Id="f2" KeyPath="yes"/>
        <File Id="f3" KeyPath="yes"/>
      </Component>
    </Directory>
  </Fragment>
  <Fragment>
    <ComponentGroup Id="cg1">
      <ComponentRef Id="c1"/>
      <ComponentRef Id="c2"/>
      <ComponentRef Id="c3"/>
    </ComponentGroup>
  </Fragment>
</Wix>
于 2013-04-12T05:59:21.363 に答える
0

これが私の答えです。ありがとうエーロ・ヘレニウス。

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="2.0" 
            xmlns="http://schemas.microsoft.com/wix/2006/wi"
            xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
            xmlns:wix="http://schemas.microsoft.com/wix/2006/wi"
            exclude-result-prefixes="wix">
    <xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes"/>

    <xsl:strip-space elements="*" />

    <xsl:key name="kRemoveComps" 
             match="wix:Directory/wix:Component[position()&gt;1]" use="@Id" />

    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="wix:Directory">
        <xsl:copy>
            <xsl:apply-templates select="@*" />
            <xsl:apply-templates select="wix:Directory" />
            <xsl:apply-templates select="wix:Component[1]" />
        </xsl:copy>
    </xsl:template>

    <xsl:template match="wix:Component[1]">
        <xsl:copy>
            <!-- Attr. -->
            <xsl:apply-templates select="@*" />

            <!-- File in this Component -->
            <xsl:apply-templates select="wix:File" />

            <!-- Files in siblings -->
            <xsl:apply-templates select="../wix:Component[position()&gt;1]/wix:File" />
        </xsl:copy>
    </xsl:template>

    <xsl:template match="wix:Component[position()&gt;1]/wix:File">
        <xsl:copy>
            <!-- Removing KeyPath Attr. -->
            <xsl:apply-templates select="@*[not(name()='KeyPath')]|node()" />
        </xsl:copy>
    </xsl:template>

    <!-- Removing ComponentRef -->
    <xsl:template match="wix:ComponentRef[key('kRemoveComps', @Id)]" />
</xsl:stylesheet>
于 2013-04-12T08:35:14.433 に答える