如果搜索参数为空白或缺失/错误,我如何使用 Xpath 函数“contains()”不返回任何内容?

Posted

技术标签:

【中文标题】如果搜索参数为空白或缺失/错误,我如何使用 Xpath 函数“contains()”不返回任何内容?【英文标题】:How can I use the Xpath function 'contains()' to return nothing if it's search param is blank or missing/false? 【发布时间】:2012-08-27 11:43:39 【问题描述】:

我正在尝试编写可以从“搜索”节点读取信息并使用它执行搜索的 Xpath 语句 (1.0)。

我取得了一些不错的进展,但偶然发现了一个问题,即如果属性(用于搜索中的值)为空或不存在,则会失败。

编辑代码以简化示例:

这是我的示例 XML:

<xml>
    <files>
        <file name="foo" description="" rating="4"/>
        <file name="food" description="" rating="4"/>
        <file name="foobar" description="" rating="3"/>
        <file name="bar" description="" rating="3"/>
        <file name="barter" description="" rating="3"/>
        <file name="barterer" description="" rating="2"/>
    </files>
    <searches>
        <search id="1">
            <exclude>
                <file term="foo"/>
            </exclude>
        </search>
    </searches>
</xml>

和工作 XPATH:

//files/file[
            not(contains(@name, //search[@id='1']/exclude/file/@term))
]

它按预期工作......

但是,如果预期的属性丢失或为空,它将无法工作。我认为是因为: contains(@attrib, "") 出于某种原因匹配所有内容,因此如果属性为 "" 或不存在,则 not() 将始终不匹配任何内容。

例如,如果我将 XML 的排除片段更改为此它会失败:

            <exclude>
                <file term=""/>
            </exclude>

还有这个:

            <exclude></exclude>

有没有办法检查空值而不执行选择?或者是否有更好的方式来构建逻辑。请记住,我不能在 Xpath2.0 中使用 Conditionals 或其他函数。

【问题讨论】:

能否请您编辑问题并描述查找搜索匹配的规则 - 这些没有提供,长 Xpath 表达式相当混乱 - 我怀疑更短的表达式可以用过的。例如:cond1 and cond2 or cond1 or cond2 可以简单地替换为更短的等效表达式 cond1 or cond2 很抱歉。我更新了代码示例以更清楚地指出我的问题。 @Futile32,也许你的 XPath 得到了 name="" 的节点,因为你没有空的,所以你什么也没有。 【参考方案1】:

为什么 Xpath 函数 contains() 搜索时返回所有内容 参数为空或缺失?

因为这是 XPath 规范所说的 contains() 函数应该做的:

如果 $arg2 的值是零长度字符串,那么函数 返回真。

您可以通过以下方式调整您的 XPath 并简化一些条件:

//files/file[
            (  
                (
                    not(//search[@id='1']/include/file/@term)
                    or
                    (
                    contains(@name, //search[@id='1']/include/file/@term) 
                    or
                    contains(@description, //search[@id='1']/include/file/@term) 
                    ) 
                )
                or
                contains(@rating, //search[@id='1']/include/file/@rating)   
            )    
            and 
            ( 
                 (
                    not(//search[@id='1']/exclude/file/@term)
                    or
                    (
                    not(contains(@name, //search[@id='1']/exclude/file/@term)) 
                    and
                    not(contains(@description, //search[@id='1']/exclude/file/@term))
                    )
                )
                and
                (
                    not(//search[@id='1']/exclude/file/@rating)
                    or
                    not(contains(@rating, //search[@id='1']/exclude/file/@rating))
                )
            )

            ]

【讨论】:

感谢您的参考,但是我想我希望找到一种方法可以不同地使用该功能来解决我的问题。我已经改写了我的问题以表明这一点。【参考方案2】:

也许你想说类似的话

//files/file[
   not(contains(@name, 
                //search[@id='1']
                /exclude/file/@term))
   or not(
     normalize-string(//search[@id='1']
                      /exclude/file/@term)
   )
]

【讨论】:

【参考方案3】:

所以我在另一篇文章中偶然发现了答案。下面是它工作的一个例子。 谢谢大家的建议。

//files/file[
    not(
        contains(
            @name,
            concat( //search[@id='1']/exclude/file/@term,
                substring('??', 1 + 2*
                    boolean( substring( //search[@id='1']/exclude/file/@term, 1 ) )
                )
            )
        )
    )
]

我放置“??”的位置可能想用无效的字符或其他东西替换。对于使用的每个附加字符,1+ 需要增加。对我来说,我正在检查文件名,所以问号似乎是个好主意。老实说,我可能不会使用这条路线,毕竟我只是渴望解决这个问题。

我的想法是从这里得到的: How to give back constant if node does not exist in XPATH?

【讨论】:

以上是关于如果搜索参数为空白或缺失/错误,我如何使用 Xpath 函数“contains()”不返回任何内容?的主要内容,如果未能解决你的问题,请参考以下文章

如何验证空白输入搜索框

Makefile空白参数导致shell错误

FreeMarker 模板错误:以下已评估为 null 或缺失 |但不是真的

TSLint 摆脱缺失的空白

如何显示选项缺失参数的错误?

如何在将jsonObject转换为模型对象时检测缺失的字段