使用xpath表达式与eXist-db时出错

时间:2011-06-01 21:04:24

标签: xml xpath exist-db

我正在使用xpath来查询包含莎士比亚戏剧的xml文件(我正在研究xpath)。 现在我想知道juliet对罗密欧的回应多少次(在他之后说话)。 我正在使用这个xpath表达式:

1: count(doc('r_and_j.xml')//SPEAKER[. = "JULIET" and ../preceding-sibling::SPEECH[1]/SPEAKER = "ROMEO"])

然而这让我回归4,而这显然是不正确的...... 但这确实有效:

2: count(doc('r_and_j.xml')//SPEECH[SPEAKER = "JULIET" and (preceding-sibling::SPEECH[1]/SPEAKER = "ROMEO")]

另一个查询,其中的东西是icky如下: 我想知道与罗密欧和朱丽叶的下一幕没有共同点的行为的标题。

3: doc('r_and_j.xml')//ACT[not(.//SPEAKER = ./following-sibling::ACT[1]//SPEAKER)]/TITLE

无法提供正确的结果,而这一结果确实如此:

4: doc('r_and_j.xml')//ACT[not(distinct-values(.//SPEAKER) = distinct-values(./following-sibling::ACT[1]//SPEAKER))]/TITLE

我不明白为什么xpath表达式1,3无法提供答案,而2,4呢?这可能与存在有关,因为我给了3作为解决方案,而它似乎没有用。

由于很难回答这个问题(至少对1,2),如果你不知道我正在研究的xml,我会在这里发布dtd:

<!-- DTD for Shakespeare    J. Bosak    1994.03.01, 1997.01.02 -->
<!-- Revised for case sensitivity 1997.09.10 -->
<!-- Revised for XML 1.0 conformity 1998.01.27 (thanks to Eve Maler) -->

<!ENTITY amp "&#38;#38;">
<!ELEMENT PLAY     (TITLE, FM, PERSONAE, SCNDESCR, PLAYSUBT, INDUCT?,
                             PROLOGUE?, ACT+, EPILOGUE?)>
<!ELEMENT TITLE    (#PCDATA)>
<!ELEMENT FM       (P+)>
<!ELEMENT P        (#PCDATA)>
<!ELEMENT PERSONAE (TITLE, (PERSONA | PGROUP)+)>
<!ELEMENT PGROUP   (PERSONA+, GRPDESCR)>
<!ELEMENT PERSONA  (#PCDATA)>
<!ELEMENT GRPDESCR (#PCDATA)>
<!ELEMENT SCNDESCR (#PCDATA)>
<!ELEMENT PLAYSUBT (#PCDATA)>
<!ELEMENT INDUCT   (TITLE, SUBTITLE*, (SCENE+|(SPEECH|STAGEDIR|SUBHEAD)+))>
<!ELEMENT ACT      (TITLE, SUBTITLE*, PROLOGUE?, SCENE+, EPILOGUE?)>
<!ELEMENT SCENE    (TITLE, SUBTITLE*, (SPEECH | STAGEDIR | SUBHEAD)+)>
<!ELEMENT PROLOGUE (TITLE, SUBTITLE*, (STAGEDIR | SPEECH)+)>
<!ELEMENT EPILOGUE (TITLE, SUBTITLE*, (STAGEDIR | SPEECH)+)>
<!ELEMENT SPEECH   (SPEAKER+, (LINE | STAGEDIR | SUBHEAD)+)>
<!ELEMENT SPEAKER  (#PCDATA)>
<!ELEMENT LINE     (#PCDATA | STAGEDIR)*>
<!ELEMENT STAGEDIR (#PCDATA)>
<!ELEMENT SUBTITLE (#PCDATA)>
<!ELEMENT SUBHEAD  (#PCDATA)>

链接到xml(以及romeo和juliet旁边的其他游戏):http://metalab.unc.edu/bosak/xml/eg/shaks200.zip

1 个答案:

答案 0 :(得分:1)

我不知道你是如何从第一个查询获得4的,因为你要求(部分)在SPEAKER元素中找到SPEAKER元素,而DTD不允许这样做。

我正在使用http://www.ibiblio.org/xml/examples/shakespeare/

处提供的XML播放文字

如果你想找到朱丽叶的所有演讲,先是R的演讲,那么(让我们建立起来)

所有演讲:

//SPEECH(返回841个元素)

朱丽叶的所有演讲:

//SPEECH[SPEAKER='JULIET'](返回118个元素)

最后:

//SPEECH[SPEAKER='JULIET' and preceding-sibling::SPEECH[1][SPEAKER='ROMEO']](返回37个元素)

你的第二个任务非常具有挑战性,但是可以使用=运算符来完成,当比较节点集时,如果集合中的任何值被共享,则返回true,所以:

//ACT[ following-sibling::ACT and not(.//SPEAKER = following-sibling::ACT[1]//SPEAKER)]/TITLE

不出所料,剧中所有相邻的Acts都有一些共同的扬声器,所以没有任何回复。