0

以下是描述我正在使用的 XML 结构的 DTD:

<!DOCTYPE bib [
<!ELEMENT bib (book+,magazine*)>
<!ELEMENT book (title,author+,publisher,editor?,price)>
<!ELEMENT magazine (title,publisher,editor+)>
<!ELEMENT title (#PCDATA)>
<!ELEMENT author (last,first)>
<!ELEMENT publisher (#PCDATA)>
<!ELEMENT editor (last, first,affiliation)>
<!ELEMENT price ((#PCDATA)>
<!ELEMENT last (#PCDATA)>
<!ELEMENT first (#PCDATA)>
<!ELEMENT affiliation (#PCDATA)>
<!ATTLIST book year CDATA #REQUIRED>
]>

我必须编写一个 XQuery 来返回 Weikum 先生是编辑之一的所有书籍或杂志。

我在确定如何归还书籍或杂志时遇到问题。这是我能想到的:

for $x in document(“bib.xml”)/bib
where $x/book/editor/lastname = “Weikum” or $x/magazine/editor/lastname = “Weikum”
return <result></result>

但这并没有达到我想要的结果。如何退回书籍或杂志元素?我应该说return $x吗?

4

2 回答 2

1

使用姓氏为“Weikum”的编辑退回书籍和杂志的最简单方法是

//editor[lastname='Weikum']/..

或者,如果您更喜欢 FLWOR 表达式,是的,您可以说return $x,如果 $x 绑定到您想要返回的内容。但是,在您的草图中并非如此:您说要退回书或杂志,但已将 $x 绑定到bib元素。你想要更像这样的东西:

for $x in document('bib.xml')/bib/*
where $x/editor/lastname='Weikum'
return $x

在这两种表述中,我利用了这样一个事实,即只有书籍和杂志才有孩子的名字editor,而且只有书籍和杂志才会以bib. 在更复杂的 DTD 中,如果您需要过滤掉小册子、标准和博客文章以获取书籍和杂志,则可能需要更复杂的表达式......

于 2013-03-10T02:15:01.543 回答
0

使用

//*[self::book or self::magazine][editor[lastname eq 'Weikum']]

从 DTD 可以清楚地看出,只有 abook或 amagazine可以有一个孩子editor

如果文档已针对此 DTD 成功验证,则表达式可以更简单:

//*[editor[lastname eq 'Weikum']]

如果我们相信 DTD,abook或 amagazine必须是 XML 文档顶部元素的子元素

这使我们能够提供一个可能更有效的表达式:

/*/*[editor[lastname eq 'Weikum']]
于 2013-03-10T05:44:56.547 回答