문제

I have a XML document representing my model that I need to parse and save in db. In some fields it may have NULL values indicated by xsi:nil. Like so

<quantity xsi:nil="true"/>

For parsing I use scala.xml DSL. The problem is I can't find any way of determining if something is nil or not. This: (elem \ "quantity") just returns an empty string which then blows up when I try to convert it to number. Also wrapping that with Option doesn't help.

Is there any way to get None, Nil or even null from that XML piece?

도움이 되었습니까?

해결책

In this case, you could use namespace URI with your XML with attribute method to get the text in the "xsi:nil" attribute.

Here is a working example:

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)

If you consider a empty node is None, then you don't even need to bother the attribute. Just filter out the node without any text inside it, and using headOption to get the value.

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

다른 팁

If you use xtract you can do this with a combination of filter and otpional:

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

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

Disclaimer: I work for Lucid Software and am a contributor to xtract.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top