我的xml文件符合以下DTD:
<!ELEMENT eprints (paper+)>
<!ELEMENT paper (eprintsid,userid,dir,datestamp,type,author+,title)>
<!ELEMENT eprintsid (#PCDATA)>
<!ELEMENT userid (#PCDATA)>
<!ELEMENT dir (#PCDATA)>
<!ELEMENT datestamp (#PCDATA)>
<!ELEMENT type (#PCDATA)>
<!ELEMENT author (#PCDATA)>
<!ELEMENT title (#PCDATA)>
<!ATTLIST author id CDATA #REQUIRED>
从这个xml文件中我想生成一个列表节点,该节点列出了作者的所有不同值文本节点,它们匹配多个id值,多个id作为子节点。
因此我尝试使用以下xquery:
let $doc := doc("eprints")
for $i in distinct-values($doc//author)
let $jn := $i/@id
where (count(distinct-values($jn)) > 1)
return <idByAuthor>{$jn}</idByAuthor>
显然XQuery不允许我遍历$i
的'id'属性节点,因为我得到以下错误(来自我的xml数据库引擎BaseX):
'@id'需要'上下文节点;找到xs:untypedAtomic。'。
有谁知道为什么我无法达到$i
的id属性?
答案 0 :(得分:4)
distinct-values(...)
返回一组原子值(例如,数字和字符串),而不是XML节点。你不能从这些步骤做轴。
从这个xml文件中我想生成一个列表节点 distinct-values作者的文本节点,匹配多个id值, 将多个id作为子节点。
这不是你要解决的问题,而是你试图解决它的方式。我想你想要查询提供一篇以上论文的所有作者(或者他们作者的作品)。如果我猜错了,请准确写下你的查询应该做什么。
尝试遵循此草图(尚未生效的XQuery):
for all authors $a
where count of all papers with author $a
return <idByAuthor>{$a/@id}</idByAuthor>
如果您需要有关此查询的更多帮助,请发布一些示例XML代码段,如果您有一些代码用于查询此代码和所需的输出。
明确问题的代码:
for $author in distinct-values($doc//author)
let $ids := $doc//author[data()=$author]/@id/data()
where count($ids) > 1
return
<author name="{ $author }">
{
for $id in $ids
return <id>{ $id }</id>
}
</author>
答案 1 :(得分:2)
你可能想看一下XQuery 3.0引入的group by
表达式(见BaseX Doc)。
分组允许您执行基于值的分组,因此您可以执行此类Gist, Group By Example中的操作:
let $authors :=
<authors>
<author id="a"><name>Foo</name>…whatever…</author>
<author id="b"><name>Foo</name>…whatever…</author>
<author id="a"><name>Foo</name>…whatever…</author>
<author id="c"><name>Bar</name>…whatever…</author>
<author id="d"><name>Bar</name>…whatever…</author>
<author id="f"><name>FooBar</name>…whatever…</author>
</authors> (: or use doc('eprints')//author :)
return
<distinct-names> {
for $author in $authors//author
group by $name := $author/name
return
if(count(distinct-values($author/@id)) > 1) then
element {"author"}
{
attribute {"name"} {$name},
for $id in distinct-values($author/@id)
return <id>{$id}</id>
}
else ()
}</distinct-names>
我希望这会有所帮助,否则请随意发布一小段XML文件。
亲切的问候 迈克尔