Выполнение сложного XPath запрашивает в Scala

Что самый простой 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, но я признаю, что не знаю среду, реальную хорошо.)

13
задан Shog9 5 May 2011 в 15:49
поделиться

3 ответа

Я думаю, что я пойду по пути легкой поддержки XOM. Немного жаль, что авторы XOM решили не раскрывать коллекции дочерних узлов и тому подобное, но у них было больше работы и меньше преимуществ сделать это на Java, чем на Scala. (А в остальном это хорошо продуманная библиотека.)

EDIT: В конце концов, я стал продвигать JDOM, потому что XOM не компилирует XPath-запросы заранее. Поскольку в этот раз большая часть моих усилий была направлена на XPath, я смог придумать хорошую модель, которая позволяет обойти большинство проблем с дженериками. Не должно быть слишком сложно придумать разумные обобщенные версии методов getChildren и getAttributes и getAdditionalNamespaces в org. jdom.Element (продвигая библиотеку новыми методами с немного измененными именами). Я не думаю, что есть исправление для getContent, и я не уверен насчет getDescendants.

3
ответ дан 1 December 2019 в 23:14
поделиться
//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, который разрешается в нужное вам пространство имен, поскольку буквальные пространства имен в поиске не поддерживаются.

12
ответ дан 1 December 2019 в 23:14
поделиться

Думаю, когда scalaxmljaxen станет зрелым, мы сможем делать это надежно на встроенных в scala классах XML.

1
ответ дан 1 December 2019 в 23:14
поделиться
Другие вопросы по тегам:

Похожие вопросы: