代码之家  ›  专栏  ›  技术社区  ›  John

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

  •  5
  • John  · 技术社区  · 17 年前

    我有一个XML文档和关联的模式,它将几个属性定义为 xs:boolean 类型。的词汇值 布尔函数 true , false , 1 0 ,因此,为了正确地选择具有特定布尔值的属性,我必须编写如下内容:

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

    @attribute='false' or @attribute='0'
    

    这似乎很冗长。

    你可能会期望 boolean(@attribute) 去工作,但是 boolean 函数有不同的语义。

    有更好的方法吗?这是一个模式感知处理器可以帮助解决的问题吗?

    6 回复  |  直到 17 年前
        1
  •  6
  •   John    17 年前

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

    @attribute=('true','1')
    string(@attribute) cast as xs:boolean
    

    最后,xpath 2.0提供了模式感知处理,这意味着如果一切都一致,那么您应该能够编写:

    data(@attribute)
    

    但是模式感知处理器似乎很难实现。最受欢迎的似乎是 saxon ,300英镑。所以现在我正在使用 @attribute=('true','1') .

        2
  •  1
  •   Phil    17 年前

    您的选项可能取决于您使用的是哪个XPath处理器。例如,微软的东西允许你定义可以用来实现“布尔(@attribute)”模式的javascript函数。我不知道其他引擎是否也有类似的支持。

    否则,我怀疑你不得不同时检查“真”和“1”。

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

        3
  •  1
  •   Tomalak    17 年前

    仅使用xpath,您建议的表达式就尽可能接近。同样的检查有不同的方法,但是所有的方法都会导致一个更长更复杂的表达式,并且隐藏更多的意图。

    我认为没有模式感知处理器,XML模式没有连接到XSLT,将对它的支持构建到处理器imho中也没有多大意义。定义了语言,扩展是公认的添加功能的标准方法。

    如果您使用的库支持exsl扩展函数,那么您可以编写一个半可移植的机制来将布尔值签入抽象为一个函数,也可以使用供应商特定的扩展,如msxsl。

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

        4
  •  1
  •   pdwetz    17 年前

    我使用一个简单的命名模板进行详细检查,并根据需要对其进行调整,以处理遗留系统(例如,某些字段可能使用“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>
    

    用途:

    <xsl:variable name="enabled">
        <xsl:call-template name="CleanupBool">
            <xsl:with-param name="val" select="IS_ENABLED"/>
        </xsl:call-template>
    </xsl:variable>
    
        5
  •  1
  •   RobF    12 年前

    尝试下列xpath表达式:

    [@attribute=true()]
    
        6
  •  0
  •   Vadim Peretokin    12 年前

    @attribute cast as xs:boolean 是一个很好的方法。