一些正确的XPath表达式不能按预期工作

时间:2017-01-11 14:26:04

标签: xslt xpath wix

我在收集注册表数据后对WiX生成的文件进行了一些XML转换。对于那些不熟悉WiX的人,只要考虑我试图在XML文件上进行XML传输,无论它来自何处。我遇到的问题是:当我使用XPath时

match="node()[name() = 'File'][not(@KeyPath)]"

然后匹配工作正常,它找到所有那些缺少KeyPath属性的File节点,但是,如果我使用另一个XPath表达式

match="//File[not(@KeyPath)]"

然后它没有找到任何匹配。

一般情况下,我不能将标准XPath与/,//,。,..一起使用,但是,下面有一个XPath示例,它可以很好地运行

<xsl:template match="node()[name() = 'File']
                               [contains(@Source, 'First.dll') or 
                                contains(@Source, 'Second.dll')]
                               [not(@Assembly)]">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()"/>
            <xsl:attribute name="Assembly">.net</xsl:attribute>
            <xsl:attribute name="KeyPath">yes</xsl:attribute>
        </xsl:copy>
    </xsl:template>

/bookstore/book[@lang='en']之类的东西不起作用。也许,我在XSL文件的开头缺少一些描述来识别像这样的Xpath。

1 个答案:

答案 0 :(得分:3)

这是因为XML文件中的节点几乎肯定在命名空间中

<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">

您的表达式//File[not(@KeyPath)]正在寻找一个没有名称空间的File元素。您需要考虑XSLT中的命名空间

所以,在xsl:stylesheet上绑定一个前缀就像这样......

<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:wix="http://schemas.microsoft.com/wix/2006/wi" />

然后你的比赛表达变成了这个......

<xsl:template match="//wix:File[not(@KeyPath)]" />

事实上,匹配中不需要//。这也会起作用

<xsl:template match="wix:File[not(@KeyPath)]" />