如何为各个元素添加值?

时间:2017-05-15 04:08:17

标签: xpath xquery marklogic marklogic-8

我有3种XML结构,如下所示:

a.xml
 <Books>
   <Book>
     <Publisher>ABC Pvt Ltd</Publisher>
     <Month>May</Month>
     <Year>2016</Year>
     <BooksReleased>4</BooksReleased>
   </Book>
 </Books>

b.xml
<Books>
   <Book>
     <Publisher>XYZ Pvt Ltd</Publisher>
     <Month>April</Month>
     <Year>2016</Year>
     <BooksReleased>2</BooksReleased>
   </Book>
 </Books>

c.xml
<Books>
   <Book>
     <Publisher>ABC Pvt Ltd</Publisher>
     <Month>June</Month>
     <Year>2016</Year>
     <BooksReleased>2</BooksReleased>
   </Book>
 </Books>

我想按发布者对这些XML进行分组,还需要计算其总数。出版物由特定年份的出版商发布。

所需的输出格式:

<TotalCalc>
  <PublishedBook>
    <Publisher>ABC Pvt Ltd</Publisher>
    <no.of books>6</no.of books>    
  </PublishedBook>
  <PublishedBook>
    <Publisher>XYZ Pvt Ltd</Publisher>
    <no.of books>2</no.of books>
  </PublishedBook>
</TotalCalc>

请帮助我,我尝试了以下但不能正常工作

typeswitch($Publisher)
case element (ABC Pvt Ltd)
  return sum($doc/BooksReleases[$doc/$Publisher = 'ABC Pvt Ltd'])
default return 'unknnown'

1 个答案:

答案 0 :(得分:1)

有可能使用cts:value-tuples来提取Publisher和'BooksReleased'的共现,然后您可以迭代以按Publisher聚合。这会扩大得多。类似的东西:

let $aggregates := map:map()
let $_ :=
  for $tuple in cts:value-tuples((
    cts:element-reference(xs:QName("Publisher")),
    cts:element-reference(xs:QName("BooksReleased"))
  ))
  let $values := json:array-values($tuple)
  let $pub := $values[1]
  let $books as xs:int := $values[2]
  return map:put($aggregates, $pub, (map:get($aggregates, $pub), 0)[1] + $books)
return $aggregates

请注意,这需要PublisherBooksReleased上的索引,并且每个文档只包含一个(值)Publisher以防止交叉产品非常重要。

我还会考虑简单地删除(或忽略)BooksReleased,并确保将每本书保存为单独的文档。然后,您可以cts:values使用Publisher并在每个发布商值上使用cts:frequency来获取发布商的图书数量。

HTH!