2

我的 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 不允许我遍历 的 'id' 属性节点$i,因为我收到以下错误(来自我的 xml 数据库引擎 BaseX):'@id' 需要上下文节点;xs:untypedAtomic 找到。

有谁知道为什么我无法达到的 id 属性$i

4

2 回答 2

4

distinct-values(...)返回一组原子值(例如,数字和字符串),而不是 XML 节点。你不能从这些做一个轴步。

从这个 xml 文件中,我想生成与多个 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>
于 2012-05-20T13:26:35.070 回答
2

您可能想看看group byXQuery 3.0 引入的表达式(请参阅BaseX Doc)。

Group by 允许您执行基于值的分组,因此您可以在此Gist 中执行类似 Group By Example的操作:

let $authors := 
<authors>
  <author id="a"><name>Foo</name>…whatever…&lt;/author>
  <author id="b"><name>Foo</name>…whatever…&lt;/author>
  <author id="a"><name>Foo</name>…whatever…&lt;/author>
  <author id="c"><name>Bar</name>…whatever…&lt;/author>
  <author id="d"><name>Bar</name>…whatever…&lt;/author>
  <author id="f"><name>FooBar</name>…whatever…&lt;/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 文件的一小段。

亲切的问候迈克尔

于 2012-05-21T10:55:25.983 回答