0

Linux でコマンド ライン ツールを使用して XPath クエリを学習しようとしています (スタンフォード大学の Class2Go コースのデータベース入門を受講しています)。本と雑誌の両方を含む本屋のBookstoreQ.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

なぜ?

アップデート:

この問題を理解するのを手伝ってくれた Francis と Michael に感謝します。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

Java クラスパスのどこかにsaxonを配置したことを前提としています。したがって、以下のクエリは上記の結果を出力します (正しくインデントされています)。

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

1 に答える 1

1

xmllib2(xmllintで使用)はXPath 1.0のみを認識しており、パスステップ((Book|Magazine)パーツ)内でユニオン演算子を使用することはできません。

XPath 1.0では、次のように記述する必要があります(/Bookstore/Book/Title | /Bookstore/Magazine/Title)/Bookstore/*[name()='Book' or name()='Magazine']/Title

この制限の根本的な理由は、XPath 1.0にはシーケンスの概念がなく、ノードセットのみがあることです。シーケンスデータ型は、XPath2およびXQuery用に作成されました。/Bookstore/(Book|Magazine)/Title各パスステップに沿ってシーケンスを渡します。ドキュメントノードのシーケンス、次にBookstoreの子要素、次にドキュメント順に並べ替えられたBookとMagazineの子要素シーケンスの和集合、次にそれらのTitle要素の子です。XPath 1.0のユニオン演算子は、2つのノードセットを別のノードセットに統合することしかできないため、パス区切り文字の前後ではなく、「最も外側の」式コンテキストに存在する必要があります。

于 2013-02-21T06:16:06.173 に答える