Как обрабатывать nil в разборе scala XML?

У меня есть XML-документ, представляющий мою модель, которую мне нужно проанализировать и сохранить в БД. В некоторых полях он может иметь значения NULL, указанные xsi:nil. Вот так

<quantity xsi:nil="true"/>

Для парсинга я использую scala.xml DSL. Проблема в том, что я не могу найти способ определить, является ли что-то нулевым или нет. Это: (elem \ "quantity") просто возвращает пустую строку, которая затем взрывается, когда я пытаюсь преобразовать ее в число. Также обертывание с помощью Option не помогает.

Есть ли способ получить None, Nil или даже null из этой части XML?


person Lubiluk    schedule 17.12.2012    source источник


Ответы (2)


В этом случае вы можете использовать URI пространства имен с вашим XML с методом attribute, чтобы получить текст в атрибуте «xsi: nil».

Вот рабочий пример:

scala> val xml = <quantity xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
xml: scala.xml.Elem = <quantity xsi:nil="true" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"></quantity>

scala> xml.attribute("http://www.w3.org/2001/XMLSchema-instance", "nil")
res0: Option[Seq[scala.xml.Node]] = Some(true)

Если вы считаете пустой узел None, то вам даже не нужно беспокоиться об атрибуте. Просто отфильтруйте узел без текста внутри него и используйте headOption для получения значения.

scala> val s1 = <quantity xsi:nil="true">12</quantity>
s1: scala.xml.Elem = <quantity xsi:nil="true">12</quantity>

scala> val s2 = <quantity xsi:nil="true"/>
s2: scala.xml.Elem = <quantity xsi:nil="true"></quantity>

scala> s1.filterNot(_.text.isEmpty).headOption.map(_.text.toInt)
res10: Option[Int] = Some(12)

scala> s2.filterNot(_.text.isEmpty).headOption.map(_.text.toInt)
res11: Option[Int] = None
person Brian Hsu    schedule 17.12.2012
comment
Спасибо, это решает. Я надеялся, что, возможно, scala.xml обрабатывает нули из коробки, но, видимо, нет. - person Lubiluk; 17.12.2012

Если вы используете xtract, вы можете сделать это с помощью комбинации filter и otpional:

(__ \ "quantity").read[Node]
  .filter(_.attribute("http://www.w3.org/2001/XMLSchema-instance", "nil").isEmpty)
  .map(_.toDouble).optional

См. https://www.lucidchart.com/techblog/2016/07/12/introduction-xtract-a-new-xml-deserialization-library-for-scala/

Отказ от ответственности: я работаю в Lucid Software и являюсь участником xtract.

person Thayne    schedule 12.07.2016