XQuery - Как создать карту, используя следующие данные?

У меня есть следующие данные:

<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 ответ

Для использования карт вам понадобится либо 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)

Другие вопросы по тегам