XQuery循环条件
我有一个遵循此DTD结构的XML文件。XQuery循环条件
<!DOCTYPE report [
<!ELEMENT report (title,section+)>
<!ELEMENT section (title,body?,section*)>
<!ELEMENT title (#PCDATA)>
<!ELEMENT body (para+)>
<!ELEMENT para(#PCDATA)>
<!ATTLIST book version CDATA #REQUIRED>
<!ATTLIST section number ID CDATA #REQUIRED>
]>
我想用XQuery查询以下两件事情。
1.获取至少出现两次的所有标题(两个标题相同的标题)。
for $x in /report/section/
for $y in /report/section/
where $x/@title = $y/@title
return $x/@title
2.获取正文或5个嵌套节中至少有10个段落的所有节的编号和标题。
for $x in /report/section/
where $x/para >= 10 or count(/section) > 10
return <large>$x/number $x/title</large>
但我的查询似乎并不正确。我是XQuery或XPath的初学者,有人能告诉我如何解决我的疑问吗?
编辑:示例XML
<?xml version="1.0" encoding="UTF-8"?>
<report version = '1'>
<title>Harry Potter</title>
<section number = '1'>
<title>sec1</title>
<body>
<para>1</para>
<para>2</para>
<para>3</para>
<para>4</para>
<para>5</para>
<para>6</para>
<para>7</para>
<para>8</para>
<para>9</para>
<para>10</para>
<para>11</para>
</body>
</section>
<section number = '2'>
<title>sec2</title>
<body><para>test</para></body>
<section number = '2.1'>
<title>sec21</title>
<body>
<para>test</para>
<para>test</para>
<para>test</para>
<para>test</para>
<para>test</para>
<para>test</para>
<para>test</para>
<para>test</para>
<para>test</para>
<para>test</para>
<para>test</para>
</body>
</section>
<section number = '2.2'>
<title>sec21</title>
<body><para>test</para></body>
</section>
<section number = '2.3'>
<title>sec23</title>
<body><para>test</para></body>
</section>
<section number = '2.4'>
<title>sec24</title>
<body><para>test</para></body>
</section>
<section number = '2.5'>
<title>sec25</title>
<body><para>test</para></body>
</section>
<section number = '2.6'>
<title>sec1</title>
<body><para>test</para></body>
</section>
</section>
</report>
在你的第一个例子中,有两个问题。首先,您没有获取嵌套部分,因为您只是迭代报表元素的直接子元素的部分元素。其次,你在同一个内容上使用两个循环。 $x
和$y
都可能是相同的元素,所以where条件将为每个部分至少匹配一次。我会写这样的:
for $x in distinct-values(/report//section/title)
where count(/report//section[title=$x]) > 1
return $x
循环得到所有独特的游戏,并遍历它们(注意,我们使用report//section
让所有后代部分)。然后,对于其中的每一个,我们计算它使用了多少次,以保持不止一次出现的次数。然后我们返回循环变量(绑定到标题)。
运行它,我们回去
sec1 sec21
在第二种情况下,我们还没有得到所有后代的同样的问题。我们也需要重视。我会用我所选择$x/body/para
得到的部分(它们出现为主体元素的儿童)的段落
for $x in /report//section
where count($x/body/para) > 9 or count($x/section) > 4
return <large>{$x/@number} {string($x/title)}</large>
通知。这个计数直接后代,但可以修改,以获得所有后代,如果有必要。还要注意在直接元素构造函数中使用大括号。当我们构造一个直接元素时,所有文本都是按字面读取的。大括号用于评估xquery表达式而不是文本文本。
我在标题中使用了字符串函数来提取元素的文本内容。如果我们不这样做,我们会得到一个实际的标题元素,而不是它的内容(这可能是一个期望的行为)。当我们提取数字属性时,它将是我们构造元素的属性(如果我们希望它是文本,我们可以将字符串函数应用于它)。
在这种情况下,它返回
<large number="1">sec1</large>
<large number="2">sec2</large>
<large number="2.1">sec21</large>
的此处示例是使用使用撒克逊-HE 9.7.0.2J的OP的提供XML(的example.xml)进行测试。只有相关部件上面出现,但完整的第一个例子跑看起来像
declare namespace output = "http://www.w3.org/2010/xslt-xquery-serialization";
declare option output:method "text";
declare context item := doc("example.xml");
for $x in distinct-values(/report//section/title)
where count(/report//section[title=$x]) > 1
return $x
和完整的第二个例子看起来像
declare namespace output = "http://www.w3.org/2010/xslt-xquery-serialization";
declare option output:method "xml";
declare context item := doc("example.xml");
for $x in /report//section
where count($x/body/para) > 9 or count($x/section) > 4
return <large>{$x/@number} {string($x/title)}</large>
现在我回头再比较我写的内容,这样做更有意义。非常感谢你! –
Matthew,你使用在线的xquery工具来测试它吗? –
@TT。不,我使用** Saxon-HE 9.7 **对OP提供的xml进行了测试。 – Matthew
对于XQuery中3.0第一个例子,我会用
declare context item := doc("example.xml");
for $x in /report//section/title/data()
group by $x
where count($x) > 1
return $x[1]
邮政样本XML和相应的预期输出请 – har07
对于示例XML,部分1和2.6具有相同的标题,和2.1和2.2节具有相同的标题。对于第二个问题,1和2.1在正文中有超过10个段落,并且2个具有超过5个嵌套段。 –