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>

$i(xmlデータベースエンジンBaseXから)次のエラーが発生するため、XQueryではの「id」属性ノードに移動できないようです。「@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 に答える