xpath - 优化 XPATH 表达式以搜索特定文本

我正在构建一个工具,该工具可以根据上传到该工具的 zip 文件中的 XML 文件自动检测是否遵循了某些最佳实践。此工具使用 XPATH 解析 XML 并确定是否满足所有预定义条件。该工具检查的标准之一是某些对象(XML 文件)是否包含名为“loggedInUser()”的函数。我试图通过使用下面的 XPATH 来实现这一点:

计数(//节点/节点//文本()[包含(文本(),'loggedInUser()')])= 0

显着简化的示例 XMPL 文件如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<processModelHaul>

    <pm>
        <nodes>
            <node>loggedInUser()</node>
            <node></node>
            <node></node>
            <node></node>
            <node></node>
            <node></node>
        </nodes>
        
    </pm>

</processModelHaul>

我遇到的挑战是开发人员可以上传很多这些文件,而且这些文件比我上面放的示例要大得多。因此,当我遍历所有文件并使用上面的 XPATH 函数时,它需要很长时间并且我遇到了超时问题。

有什么方法可以优化上面的 XPATH 表达式以使其运行得更快吗?

编辑

我用来调试代码的 MariaDB 中的 SQL 查询是:

SELECT
    `CR_getXpathOutput`(`RO`.`OBJECT_CONTENT`, `C`.`XPATH`) AS `CRITERIA`
FROM
    `CR_REVIEW_OBJECT` `RO`
JOIN `CR_CRITERIA` `C` ON
    `C`.`OBJECT_TYPE` = `RO`.`OBJECT_TYPE` AND SUBMISSION_ID=127 AND IS_ACTIVE=1 AND C.OBJECT_TYPE='Process Model' AND C.DISPLAY_VALUE='loggedInUser() detected'.

RO.OBJECT_CONTENT 是 XML 文件,C.XPATH 是来自 table CR_CRITERIA 的表达式 (//nodes/node[text()='loggedInUser()'])[1]。 CR_CRITERIA 是一个参考数据table,我在其中维护不同的XPATH。这里 CR_getXpathOutput 是一个函数,定义如下:

创建函数 CR_getXpathOutput(ky LONGTEXT, xpath TEXT) 返回文本字符集 utf8 DETERMINISTIC BEGIN RETURN CAST( EXTRACTVALUE(ky, xpath) AS CHAR );结束

回答1

首先:将问题中的 XPath 更改为:

count(//nodes/node//text()[contains(., 'loggedInUser()')]) = 0

因此,将 contains-function 中的 text() 替换为 .,因为您已经在该上下文中。

我不会使用 count 而是反过来做。如果你找到了,就让引擎停止搜索。因此它不必做所有的 xml。

如果您显示的 xml 结构始终相同,这意味着文本 loggedInUser() 将始终位于此 XPath: /processModelHaul/pm/nodes/node 中,并且该节点没有任何其他文本,则使用此 XPath:

(/processModelHaul/pm/nodes/node[text()='loggedInUser()'])[1]

如果该节点可以在任何地方但总是有一个父节点,请使用此 XPath:

(//nodes/node[text()='loggedInUser()'])[1]

如果在 MySql/MariaDB 中使用,您可以尝试:

not(exists(//nodes/node[text()='loggedInUser()'))

相似文章

scrapy - AttributeError: 'set' 对象没有属性 'getall'

我有一个scrapy项目,我试图以有限的经验完成它。我已经完成了nextPage和innerPage操作。我的代码分别搜索广告并从中一个一个地抓取数据。之后,它移动到下一页。我用一两个变量检查了所有步...