如何在XPath中选择布尔值节点?

如何在XPath中选择布尔值节点?,xpath,xsd,Xpath,Xsd,我有一个XML文档和关联的模式,它定义了几个属性,这些属性具有xs:boolean类型。xs:boolean的词法值是true、false、1和0,因此,要正确选择具有特定布尔值的属性,我必须编写如下代码: @attribute='true' or @attribute='1' 或 这似乎很冗长 您可能希望像boolean(@attribute)这样的函数可以工作,但函数具有不同的语义 有更好的办法吗?这是否是架构感知处理器可以帮助的?您的选项可能取决于您使用的XPath处理器。例如,Micr

我有一个XML文档和关联的模式,它定义了几个属性,这些属性具有
xs:boolean
类型。
xs:boolean
的词法值是
true
false
1
0
,因此,要正确选择具有特定布尔值的属性,我必须编写如下代码:

@attribute='true' or @attribute='1'

这似乎很冗长

您可能希望像
boolean(@attribute)
这样的函数可以工作,但函数具有不同的语义


有更好的办法吗?这是否是架构感知处理器可以帮助的?

您的选项可能取决于您使用的XPath处理器。例如,Microsoft stuff允许您定义JavaScript函数,您可以使用这些函数实现“boolean(@attribute)”模式。我不知道其他引擎是否有类似的支持

否则,我怀疑您必须同时检查“true”和“1”


希望其他人有一个更好的答案。

仅使用XPath,您提出的表达式就非常接近了。进行同一检查有不同的方法,但所有这些方法都会导致更长、更复杂的表达,并更多地隐藏意图

我认为没有一个模式感知处理器,XMLSchema没有连接到XSLT,在处理器IMHO中构建对它的支持也没有多大意义。语言已经定义,扩展是添加功能的公认标准方式

如果所使用的库支持EXSL扩展函数,则可以编写半可移植机制将布尔检查抽象为函数,也可以使用特定于供应商的扩展(如MSXSL)来实现


我认为最好保持你的表情。它并不复杂,只是有点冗长。

除了Phil和Tomalak提出的解决方案之外,我发现XPath 2.0提供了一些替代方案:

@attribute=('true','1')
string(@attribute) cast as xs:boolean
最后,XPath 2.0确实提供了模式感知处理,这意味着如果所有内容都一致,您应该能够编写:

data(@attribute)

但模式感知处理器似乎很难找到。最受欢迎的似乎是非免费的商业版本,价格为300英镑。因此,现在我使用的是
@attribute=('true','1')
我使用一个简单的命名模板来进行详细检查,并根据需要对其进行调整,以处理遗留系统(例如,一些字段可能使用“Y”/“N”,一些字段可能使用“true”/“False”,其他字段使用1/0)并将值转储到一个变量中。这并不是最优雅的方法,但如果您使用的是XPath 1.0,不支持EXSLT,并且不能(或不想)利用外部脚本调用,那么它可以始终如一地工作,并且可以根据需要进行调整

<xsl:template name="CleanupBool">
    <xsl:param name="val" />
    <xsl:choose>
        <xsl:when test="$val='1'">1</xsl:when>
        <xsl:when test="$val='true'">1</xsl:when>
        <xsl:when test="$val='True'">1</xsl:when>
        <xsl:when test="$val='TRUE'">1</xsl:when>
        <xsl:when test="$val='T'">1</xsl:when>
        <xsl:when test="$val='Y'">1</xsl:when>
        <xsl:otherwise>0</xsl:otherwise>
    </xsl:choose>
</xsl:template>

1.
1.
1.
1.
1.
1.
0
用法:

<xsl:variable name="enabled">
    <xsl:call-template name="CleanupBool">
        <xsl:with-param name="val" select="IS_ENABLED"/>
    </xsl:call-template>
</xsl:variable>

尝试以下XPath表达式:

[@attribute=true()]

@将属性转换为xs:boolean
是一种很好的方法

[@attribute=true()]