0

我正在使用 xpath 来查询包含莎士比亚戏剧的 xml 文件(我正在研究 xpath)。现在我想知道朱丽叶对罗密欧的回应有多少次(紧跟在他身后)。我正在使用这个 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")]

另一个令人讨厌的问题如下:我想知道与罗密欧与朱丽叶中的下一幕没有共同发言人的表演的标题。

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 作为解决方案,而它似乎不起作用。

由于如果您不知道我正在处理的 xml 很难回答这个问题(至少对于 1,2),我将在此处发布 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(以及罗密欧与朱丽叶旁边的其他戏剧)的链接:http: //metalab.unc.edu/bosak/xml/eg/shaks200.zip

4

1 回答 1

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

不出所料,剧中所有相邻的章节都有一些共同的扬声器,因此没有返回任何内容。

于 2011-06-01T21:40:18.543 回答