XQuery - 如何使用以下数据创建地图?

时间:2015-12-01 02:56:30

标签: xml xpath saxon xpath-3.0

我有以下数据:

<courses>
    <course subjectId="3" name="World War II"/>
    <course subjectId="5" name="Algebra I"/>
    <course subjectId="5" name="Statistics"/>
    <course subjectId="15" name="Physics"/>
    <course subjectId="5" name="Algebra II"/>
    <course subjectId="15" name="Chemistry"/>
</courses>

我希望创建一个xpath脚本,以便生成以下映射:

map {
   '3': ('<course subjectId="3" name="World War II"/>'),
   '5': ('<course subjectId="5" name="Algebra I"/>', '<course subjectId="5" name="Algebra II"/>', '<course subjectId="5" name="Statistics"/>'),
   '15': ('<course subjectId="15" name="Physics"/>', '<course subjectId="15" name="Chemistry"/>')
}

我该怎么做?

1 个答案:

答案 0 :(得分:2)

要使用地图,您需要XPath 3.1,XQuery 3.1或XSLT 3.0。

纯XPath 3.1解决方案

map:merge(
  for $x in distinct-values(course/@subjectId) 
  return map{$x : 
             course[@subjectId = $x] ! 
               serialize(., map{'method':'xml', 'omit-xml-declaration':true()})
             }) 

但我不确定你为什么要创建一个包含序列化为XML字符串的节点的地图。将节点本身放在地图值中似乎更有用。

===已经修改过的答案===

在您的评论中,您已更改了您的要求,以便

  • 你想要一个XQuery解决方案而不是XPath
  • 您希望地图包含相关节点,而不是节点的XML序列化。

这意味着您可以:

map:merge(
  for $x in course
  group by $id := $x/@subjectId 
  return map{$id : $x})

(未经测试:请告诉我们是否有效!请注意,它需要XQuery 3.1)