Что самый простой API должен использовать в scala для выполнения следующих запросов XPath на документе?
//s:Annotation[@type='attitude']/s:Content/s:Parameter[@role='type' and not(text())]
//s:Annotation[s:Content/s:Parameter[@role='id' and not(text())]]/@type
(s
определяется как псевдоним для конкретного пространства имен),
Единственная документация, которую я могу найти на библиотеках XML Scala, не имеет никакой информации о выполнении сложных реальных запросов XPath.
Я раньше любил JDOM с этой целью (в Java), но так как JDOM не поддерживает дженериков, это будет болезненно для работы с в Scala. (Другие библиотеки XML для Java были склонны быть еще более болезненными в Java, но я признаю, что не знаю среду, реальную хорошо.)
Я думаю, что я пойду по пути легкой поддержки XOM. Немного жаль, что авторы XOM решили не раскрывать коллекции дочерних узлов и тому подобное, но у них было больше работы и меньше преимуществ сделать это на Java, чем на Scala. (А в остальном это хорошо продуманная библиотека.)
EDIT: В конце концов, я стал продвигать JDOM, потому что XOM не компилирует XPath-запросы заранее. Поскольку в этот раз большая часть моих усилий была направлена на XPath, я смог придумать хорошую модель, которая позволяет обойти большинство проблем с дженериками. Не должно быть слишком сложно придумать разумные обобщенные версии методов getChildren
и getAttributes
и getAdditionalNamespaces
в org. jdom.Element
(продвигая библиотеку новыми методами с немного измененными именами). Я не думаю, что есть исправление для getContent
, и я не уверен насчет getDescendants
.
//s:Annotation[@type='attitude']/s:Content/s:Parameter[@role='type' and not(text())]
Я не понимаю нотацию s:
и не могу найти ее в спецификации XPath. Однако, игнорируя это, это будет выглядеть так:
(
(xml
\\ "Annotation"
filter (_ \ "@type" contains Text("x"))
)
\ "Content"
\ "Parameter"
filter (el => (el \ "@type" contains Text("type")) && el.isInstanceOf[Text])
)
Обратите внимание на необходимость скобок из-за более высокого приоритета \
над фильтром
. Я изменил форматирование на многострочное выражение, поскольку эквивалент Scala слишком подробен для одной строки.
Однако я не могу ответить о пространствах имен. Не знаю, как с ними работать при поиске, если это вообще возможно. В документах упоминается @ {uri} атрибут
для атрибутов с префиксом, но ничего не упоминается о элементах с префиксом. Также обратите внимание, что вам необходимо передать uri, который разрешается в нужное вам пространство имен, поскольку буквальные пространства имен в поиске не поддерживаются.
Думаю, когда scalaxmljaxen станет зрелым, мы сможем делать это надежно на встроенных в scala классах XML.