2013-11-28 29 views
1

我是XSL newb,並且很難理解語法。 我想要實現的是從XML和其引用的節點中刪除節點。這個xml是通過運行WIX Installer提供的工具Heatdirectory構建的。 因此,文件中的所有內容都是動態創建的。我對文件知道的一件事就是我想刪除引用的文件的名稱。使用xsl在xml中刪除自引用節點

這是和示例XML:

<?xml version="1.0" encoding="utf-8"?> 
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"> 
    <Fragment> 
     <DirectoryRef Id="InstallFolder"> 
      <Component Id="cmpAEC985F4FAA50E51011E84E93A32F283" Guid="{3574FFF9-F47D-4A3F-A975-64D76546068A}"> 
       <File Id="fil9C01928D57F128482FD2A78A209FBF95" KeyPath="yes" Source="$(var.SourcePath)\AppSettings.config" /> 
      </Component> 
      <Component Id="cmp10AE81284551BB54849628AE519965C7" Guid="{CF245728-B329-454E-A305-BE33FC818572}"> 
       <File Id="fil3F1ECB9AAE6412D0FDF9577B44764BA9" KeyPath="yes" Source="$(var.SourcePath)\CsvHelper.dll" /> 
      </Component> 
      <Component Id="cmp596F6F97E366DDB8E0770EC1550C6CB5" Guid="{D8E5EF9E-CB20-4C40-BD02-D79364EC6518}"> 
       <File Id="filE48072B3494220F703E4B206DF9D2664" KeyPath="yes" Source="$(var.SourcePath)\CsvHelper.pdb" /> 
      </Component> 
     </DirectoryRef> 
    </Fragment>   
    <Fragment> 
     <ComponentGroup Id="FileComponents"> 
      <ComponentRef Id="cmpAEC985F4FAA50E51011E84E93A32F283" /> 
      <ComponentRef Id="cmp10AE81284551BB54849628AE519965C7" /> 
      <ComponentRef Id="cmp596F6F97E366DDB8E0770EC1550C6CB5" />   
     </ComponentGroup> 
    </Fragment> 
</Wix>  

這是我的XSLT是去除組件,我想刪除。

<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:msxsl="urn:schemas-microsoft-com:xslt" 
    exclude-result-prefixes="msxsl" 
    xmlns:wix="http://schemas.microsoft.com/wix/2006/wi"> 
    <xsl:output method="xml" indent="yes" /> 
    <xsl:strip-space elements="*"/> 
    <xsl:output omit-xml-declaration="yes"/> 
    <xsl:template match="node()|@*"> 
     <xsl:copy> 
      <xsl:apply-templates select="node()|@*"/> 
     </xsl:copy> 
    </xsl:template> 

    <xsl:template match="wix:Component[contains(wix:File/@Source,'CsvHelper.pdb')]"/> 
</xsl:stylesheet> 

這是我從中得到的。

<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"> 
    <Fragment> 
     <DirectoryRef Id="InstallFolder"> 
     <Component Id="cmpAEC985F4FAA50E51011E84E93A32F283" Guid="{3574FFF9-F47D-4A3F-A975-64D76546068A}"> 
      <File Id="fil9C01928D57F128482FD2A78A209FBF95" KeyPath="yes" Source="$(var.SourcePath)\AppSettings.config"/> 
     </Component> 
     <Component Id="cmp10AE81284551BB54849628AE519965C7" Guid="{CF245728-B329-454E-A305-BE33FC818572}"> 
      <File Id="fil3F1ECB9AAE6412D0FDF9577B44764BA9" KeyPath="yes" Source="$(var.SourcePath)\CsvHelper.dll"/> 
     </Component> 
     </DirectoryRef> 
    </Fragment> 
    <Fragment> 
     <ComponentGroup Id="FileComponents"> 
     <ComponentRef Id="cmpAEC985F4FAA50E51011E84E93A32F283"/> 
     <ComponentRef Id="cmp10AE81284551BB54849628AE519965C7"/> 
     <ComponentRef Id="cmp596F6F97E366DDB8E0770EC1550C6CB5"/> 
     </ComponentGroup> 
    </Fragment> 
</Wix> 

但我ASLO想刪除ComponentRef引用到已刪除組件。 誰能告訴我如何做到這一點? PS:我試着創建一個包含組件ID的變量(因爲我不知道這個,不能把它放到我的XSLT文件中)。但後來我無法到達CompenentGroup並刪除ComponentRef。

回答

1

將要刪除的組件的ID存儲在變量中。然後,您可以在需要查找某個特定component時參考它。你正確地猜測這可能是解決方案。這是你如何做到的。

我向標識轉換模板添加了第二個例外(即模板),該標識轉換模板刪除了所述component reference

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

<xsl:output method="xml" indent="yes" /> 
<xsl:strip-space elements="*"/> 
<xsl:output omit-xml-declaration="yes"/> 

<xsl:variable name="del-id" select="//wix:Component[contains(wix:File/@Source,'CsvHelper.pdb')]/@Id"/> 

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

<xsl:template match="wix:Component[@Id=$del-id]"/> 

<xsl:template match="wix:ComponentRef[@Id=$del-id]"/> 

</xsl:stylesheet> 

編輯:這裏是沒有模板匹配使用變量另一種解決方案。雖然這有點長。

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

<xsl:output method="xml" indent="yes" /> 
<xsl:strip-space elements="*"/> 
<xsl:output omit-xml-declaration="yes"/> 

<xsl:variable name="del-id" select="//wix:Component[contains(wix:File/@Source,'CsvHelper.pdb')]/@Id"/> 

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

<xsl:template match="wix:ComponentGroup"> 
    <xsl:copy> 
    <xsl:copy-of select="@*"/> 
    <xsl:for-each select="wix:ComponentRef"> 
     <xsl:choose> 
      <xsl:when test="@Id=$del-id"/> 
      <xsl:otherwise> 
       <xsl:copy> 
       <xsl:apply-templates select="node()|@*"/> 
       </xsl:copy> 
      </xsl:otherwise> 
     </xsl:choose> 
    </xsl:for-each> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="wix:DirectoryRef"> 
    <xsl:copy> 
    <xsl:copy-of select="@*"/> 
    <xsl:for-each select="wix:Component"> 
     <xsl:choose> 
      <xsl:when test="@Id=$del-id"/> 
      <xsl:otherwise> 
       <xsl:copy> 
       <xsl:apply-templates select="node()|@*"/> 
       </xsl:copy> 
      </xsl:otherwise> 
     </xsl:choose> 
    </xsl:for-each> 
    <xsl:for-each select="wix:Directory"> 
     <xsl:copy> 
      <xsl:apply-templates select="node()|@*"/> 
     </xsl:copy> 
    </xsl:for-each> 
    </xsl:copy> 
</xsl:template> 

</xsl:stylesheet> 
+0

謝謝:)太簡單了!!! ..但是當你不明白語法的時候,真是太難過了:)我最初失去的時候我的自我是雙斜槓(** // **)在** wix:component **前聲明變量:) –

+0

不客氣。很高興我能幫上忙。 –

+0

所以現在到百萬美元的問題......我如何用XSL 1.0來做到這一點?導致編譯器對匹配中使用的變量提出投訴。它表示它不支持中的變量 –