xml
  • xslt
  • xpath
  • 2011-11-02 67 views 1 likes 
    1

    我有一個試圖抓住特定文件節點的父節點的XPath查詢。當我在Xselerator中使用XPath評估器時,查詢結果很好,但是當我將它放入我的XSLT代碼中時,它給了我適合。這裏是我的XSLT代碼:爲什麼XSLT不像我的XPath查詢?

    <xsl:template match="//*[local-name()='Wix']/*[local-name()='Fragment'][1]/*[local-name()='DirectoryRef']/*[local-name()='Directory'][./@*[local-name()='Name'][.='bin']]/*[local-name()='Component']/*[local-name()='File'][./@*[local-name()='Source'][.='!(wix.SourceDeployDir)\bin\Client.exe']]/.."> 
    <xsl:copy> 
        <xsl:apply-templates select="@* | node()" /> 
        <xsl:element name="RemoveFolder" namespace="{namespace-uri()}"> 
        <xsl:attribute name="Id">DeleteShortcutFolder</xsl:attribute> 
        <xsl:attribute name="Directory">DesktopFolder</xsl:attribute> 
        <xsl:attribute name="On">uninstall</xsl:attribute> 
        </xsl:element> 
    </xsl:copy> 
    

    任何想法?

    編輯:下面是有關XML(從大文件清理):

    <?xml version="1.0" encoding="utf-8"?> 
    <Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"> 
    <Fragment> 
    <DirectoryRef Id="INSTALLLOCATION"> 
    <Directory Id="dirBD8892FBCC64DA5924D7F747259B8B87" Name="bin"> 
    <Component Id="cmp92DC8F5323DA73C053179076052F92FF" Guid="{533500C1-ACB2-4A8D-866C-7CDB1DE75524}"> 
            <File Id="fil7C1FC50442FC92D227AD1EDC1E6D259F" KeyPath="yes" Source="!(wix.SourceDeployDir)\bin\Client.exe"> 
             <Shortcut Id="startmenuAdv" Directory="DesktopFolder" Advertise="yes" Name="!(wix.ProductName)" WorkingDirectory="INSTALLDIR" Icon="Icon.exe"> 
             <Icon Id="Icon.exe" SourceFile="!(wix.SourceDeployDir)\Safeguard.SPI2.Client.exe" /> 
             </Shortcut> 
             <netfx:NativeImage Id="ClientNativeImageId" Platform="64bit" Priority="0" AppBaseDirectory="INSTALLLOCATION" xmlns:netfx="http://schemas.microsoft.com/wix/NetFxExtension" /> 
            </File> 
           </Component></Directory></DirectoryRef></Fragment></Wix> 
    

    所有我希望能夠做的就是搶的組件節點。 Visual Studio給了我以下錯誤:只有'子'和'屬性'軸被允許在謂語外的模式中。 ...在\ Client.exe']]/- > .. < -

    +0

    如果沒有輸入XML的示例,則無法判斷。 – Oded

    回答

    4

    那麼XSLT匹配模式不允許所有類型的XPath表達式,相反,模式是XPath表達式的一個子集。您似乎想要訪問父項..,但不允許您使用XSLT模式執行此操作,除非它位於謂詞的內部。所以你需要重寫你的模式,而不是foo[predicate]/..使用*[foo[predicate]]

    根據您的最新評論做

    <xsl:template match="@* | node()"> 
        <xsl:copy> 
        <xsl:apply-templates select="@* | node()"/> 
        </xsl:copy> 
    </xsl:template> 
    
    <xsl:template xmlns:wi="http://schemas.microsoft.com/wix/2006/wi" 
        match="wi:Component[wi:File[@Source[. = '!(wix.SourceDeployDir)\bin\Client.exe']]]"> 
        <xsl:copy> 
        <xsl:apply-templates select="@* | node()"/> 
        <xsl:element name="RemoveFolder" namespace="{namespace-uri()}"> 
         <xsl:attribute name="Id">DeleteShortcutFolder</xsl:attribute> 
         <xsl:attribute name="Directory">DesktopFolder</xsl:attribute> 
         <xsl:attribute name="On">uninstall</xsl:attribute> 
        </xsl:element> 
        </xsl:copy> 
    </xsl:template> 
    

    可能就夠[編輯] (假設你要複製的一切,但組件,您添加的元素。

    +0

    我對此有點困惑。在這種情況下,我應該在哪裏放置括號? – IronMan84

    +0

    你的路徑長得足以混淆任何人,但我認爲'match =「* [local-name()='Wix']/* [local-name()='Fragment'] [1]/* [local-名稱()= 'DirectoryRef']/* [本地名稱()= '目錄'] [./@* [本地名稱()= '名稱'] [。= '本']/* [局地名稱()= '組件'] [* [本地名稱()= '文件'] [./@* [本地名稱()= '源'] [。='!(wix.SourceDeployDir)\ BIN \ Client.exe']]]「'可能會。您可能想告訴我們您的輸入示例需要哪種輸出,以便我們可以使用XSLT建議更簡單或更易讀的方式來實現您想要的功能。 –

    +0

    我想獲取該特定文件(Client.exe)的組件節點,以便我可以注入該刪除文件夾參數。我也試圖找到使用contains函數的更簡單的方法,但我有另一個引用Client.exe.config的組件,因此只需要詢問Client.exe就行不通。 – IronMan84

    1

    我認爲這將是更好的將更多的選擇邏輯放在apply-templates指令中,用於選擇要處理的節點,而模板規則中的選擇邏輯更少。模板規則的匹配模式可能應匹配規則可合理使用的所有元素,以及如果你不想處理所有這些元素,那麼選擇你所做的想要在apply-templates調用中處理。

    相關問題