返回不同节点的属性时出错

时间:2012-05-20 12:35:09

标签: xquery basex

我的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属性?

2 个答案:

答案 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文件。

亲切的问候 迈克尔