Удаление нежелательных узлов из файла wxs с помощью преобразования xslt

Я пытаюсь очистить файл wxs, созданный программойheat.exe, применяя преобразования xml.

Ниже приведен пример вывода файлаheat.exe.

<?xml version="1.0" encoding="utf-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
    <Fragment>
            <DirectoryRef Id="APPFOLDER">
                <Component Id="cmp78E9FF58917B1844F3E9315A285F3147" Guid="SOME-GUID">
                    <File Id="fil093D6D7CB723B5B62730D7B4E575F154" KeyPath="yes" Source="PQR.Some.dll" />
                </Component>
                <Component Id="cmp0B084126FAE7577FD84DB29766AC6C2B" Guid="SOME-GUID">
                    <File Id="filB20C8708D7EB02EDFBCC4D70F9FE7F8A" KeyPath="yes" Source="ABC.Another.dll" />
                </Component>
                <Component Id="cmp83BB1954DECD7D949AAE4ACA68806EC3" Guid="SOME-GUID">
                    <File Id="fil0E29FBFF7DB39F307A2EE19237A0A579" KeyPath="yes" Source="ABC.OneMore.dll" />
                </Component>
            </DirectoryRef>
        </Fragment>
        <Fragment>
            <ComponentGroup Id="AppFiles">
                <ComponentRef Id="cmp78E9FF58917B1844F3E9315A285F3147" />
                <ComponentRef Id="cmp0B084126FAE7577FD84DB29766AC6C2B" />
                <ComponentRef Id="cmp83BB1954DECD7D949AAE4ACA68806EC3" />
            </ComponentGroup>
        </Fragment>
    </Wix>

Я хочу удалить узлы Component, чьи дочерние узлы File имеют атрибут Source, содержащий строку «ABC». Я знаю, как найти такие узлы, используя правильные шаблоны сопоставления. Поэтому, прежде чем удалить узел Component, я хочу сохранить идентификатор компонента, а затем использовать его для удаления узла ComponentRef с идентификатором, который я только что записал.

Есть ли способ добиться этого с помощью XML-преобразования? Я думаю, что ищу что-то, где я могу создать переменную, скажем, «X», чтобы сохранить идентификатор узла компонента, который я удаляю, и использовать «X», чтобы найти удаляемые узлы ComponentRef.


person Vaibhav Pingle    schedule 09.03.2013    source источник


Ответы (1)


Вы можете сделать это без переменных. Так:

<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" indent="yes" omit-xml-declaration="yes"/>
  <xsl:strip-space elements="*"/>
  <xsl:key name="kCompsToRemove"
           match="wi:Component[contains(wi:File/@Source, 'ABC')]"
           use="@Id" />

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

  <xsl:template match="*[self::wi:Component or self::wi:ComponentRef]
                        [key('kCompsToRemove', @Id)]" />
</xsl:stylesheet>

При запуске на вашем образце ввода это производит:

<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
  <Fragment>
    <DirectoryRef Id="APPFOLDER">
      <Component Id="cmp78E9FF58917B1844F3E9315A285F3147" Guid="SOME-GUID">
        <File Id="fil093D6D7CB723B5B62730D7B4E575F154" KeyPath="yes" Source="PQR.Some.dll" />
      </Component>
    </DirectoryRef>
  </Fragment>
  <Fragment>
    <ComponentGroup Id="AppFiles">
      <ComponentRef Id="cmp78E9FF58917B1844F3E9315A285F3147" />
    </ComponentGroup>
  </Fragment>
</Wix>
person JLRishe    schedule 09.03.2013
comment
Если вы хотите удалить более одного элемента, просто добавьте дополнительные условия к атрибуту соответствия: <xsl:key name="kCompsToRemove" match="wi:Component[contains(wi:File/@Source, '.nupkg') or contains(wi:File/@Source, 'my-debug-file')]" use="@Id" /> - person HenningJ; 11.07.2016