当前位置: 首页 > 知识库问答 >
问题:

为什么这是一个使用Xmllint的XPath无效查询表达式,但对Saxon有效?

杨凯旋
2023-03-14

我正在尝试使用Linux中的命令行工具学习XPath查询(我正在学习斯坦福大学的Class2Go数据库入门课程)。给定一个包含书籍和杂志的书店的名为Bookstore Q. xml的XML文件,我可以在命令行运行以下查询:

$ java -cp Saxon-HE-9.4.0.6.jar net.sf.saxon.Query -s:"BookstoreQ.xml" \
       -qs:'<results>{/Bookstore/(Book|Magazine)/Title}</results>'

它将返回以下结果:

<?xml version="1.0" encoding="UTF-8"?>
<results>
  <Title>A First Course in Database Systems</Title>
  <Title>Database Systems: The Complete Book</Title>
  <Title>Hector and Jeff's Database Hints</Title>
  <Title>Jennifer's Economical Database Hints</Title>
  <Title>National Geographic</Title>
  <Title>National Geographic</Title>
  <Title>Newsweek</Title>
  <Title>Hector and Jeff's Database Hints</Title>
</results>

如果在命令行使用xmllint,我会得到相同的结果,如下所示:

$ xmllint --xpath '/Bookstore/Book/Title | /Bookstore/Magazine/Title'

但是,如果我尝试使用与Saxon示例中相同的精确XPath查询,则会出现如下错误:

$ xmllint --xpath '/Bookstore/(Book|Magazine)/Title' BookstoreQ.xml
XPath error: Invalid Expression
/Bookstore/(Book|Magazine)/Title
           ^
xmlXPathEval: evaluation failed
XPath evaluation failure

为什么?

感谢弗朗西斯和迈克尔帮助我理解这个问题。在linux中,在命令行上使用XPath的一种解决方法是使用类似于以下脚本的内容。

#!/bin/bash
# This script to run xpath queries
java -cp Saxon-HE-9.4.0.6.jar net.sf.saxon.Query -qs:"<results>{$1}</results>" \ 
\!indent=yes
echo

它假设您已经将saxon放在Java类路径的某个地方。因此,以下查询将输出上述结果(正确缩进):

$ xpath.sh "doc('BookstoreQ.xml')/Bookstore/(Book|Magazine)/Title"

共有1个答案

赵高雅
2023-03-14

xmllib2(由xmllint使用)只知道XPath 1.0,它不能在路径步骤((Book|Magazine)部分)中使用联合运算符。

在XPath 1.0中,您必须编写(/Bookstore/Book/Title |/Bookstore/Magazine/Title)/Bookstore/*[name()=“Book”或name()=“Magazine”]/Title

这种限制的根本原因是XPath 1.0没有序列的概念,只有节点集。序列数据类型是为XPath 2和XQuery创建的/Bookstore/(Book | Magazine)/Title沿着每个路径步骤传递一个序列:与文档节点的序列,然后是Bookstore子元素,然后是按文档顺序排序的图书和杂志子元素序列的并集,然后是这些子元素的Title元素。XPath 1.0的联合运算符只能将两个节点集统一为另一个节点集,因此它必须位于“最外层”表达式上下文中,而不是在路径分隔符之前或之后。

 类似资料: