Xml 查找XQuery中一个文档中存在但另一个文档中不存在的元素的有效方法

Xml 查找XQuery中一个文档中存在但另一个文档中不存在的元素的有效方法,xml,xpath,xquery,saxon,xquery-3.0,Xml,Xpath,Xquery,Saxon,Xquery 3.0,我有以下数据: <Subjects> <Subject> <Id>1</Id> <Name>Maths</Name> </Subject> <Subject> <Id>2</Id> <Name>Science</Name> </Subject>

我有以下数据:

<Subjects>
    <Subject>
        <Id>1</Id>
        <Name>Maths</Name>
    </Subject>
    <Subject>
        <Id>2</Id>
        <Name>Science</Name>
    </Subject>
    <Subject>
        <Id>2</Id>
        <Name>Advanced Science</Name>
    </Subject>
    <Subject>
        <Id>500</Id>
        <Name>XYZ</Name>
    </Subject>
    <Subject>
        <Id>1000</Id>
        <Name>ABC</Name>
    </Subject>
</Subjects>

1.
数学
2.
科学类
2.
高等科学
500
XYZ
1000
基础知识
以及:


1.
代数
1.
代数
1.
百分比
2.
物理
2.
生物
我希望能够使用
500
1000
获取
subject
元素,因为它们不会出现在第二个XML文档中


如何以最有效的方式做到这一点(请记住,我有大约750个科目,每个科目有120门课程)?

效率取决于您的优化器,但既然您在标签中提到了Saxon,我想这就是我们的目标。假设将变量
$subjects
$courses
分别绑定到
元素,最简单的查询可能是

$subjects/Subject[not(Id = $courses/Course/SubjectId)]
作为第一步,我会尝试运行它,看看它是否在可接受的时间内产生正确的结果;从那时起,它的性能调整工作。对于性能调整,请确保您有不同大小的源文档,以便可以测量性能如何随文档大小而变化

通常,对于连接查询,Saxon EE在优化方面比Saxon HE做得好得多,但我怀疑它在这方面会取得多大成功,因为谓词表示为否定。所以这可能会有二次性能

为了手动优化,我将建立一个索引。在XSLT中可以使用xsl:key完成,而在XQuery3.1中可以使用映射完成。定义包含$courses中显示的所有主题的地图:

let $courseSubjects := map:merge($courses/Course/SubjectId ! map{.: true()})
然后使用此选项选择:

return $subjects/Subject[not(map:contains($courseSubjects, Id))]
后记
我低估了Saxon EE优化器。实际上,它确实生成了一个索引来支持对该联接的评估。因此,创建自己的地图可能是非常不必要的。但是我还没有做任何测量。

你可以发布你目前采取/尝试的方法吗?第一种方法将我整个脚本的性能从30000ms提高到了7000ms。第二次将其进一步降低到4000毫秒左右!两者都能产生正确的输出!谢谢
return $subjects/Subject[not(map:contains($courseSubjects, Id))]