Пример обработки xml, но с использованием анти-xml вместо Scala xml

Я хотел бы переписать ниже script, используя http://anti-xml.org вместо Scala XML.

Это выдержка из главы 10. Хеширование XML в Scala - http://ofps.oreilly.com/titles/9780596155957/HerdingXMLInScalaDSLs.html

// code-examples/XML/reading/pattern-matching-script.scala
import scala.xml._
val someXML =
 <sammich>
   <bread>wheat</bread>
   <meat>salami</meat>
   <condiments>
     <condiment expired="true">mayo</condiment>
     <condiment expired="false">mustard</condiment>
   </condiments>
</sammich>

someXML match {
 case <sammich>{ingredients @ _*}</sammich> => {
    for (cond @ <condiments>{_*}</condiments> <- ingredients)
      println("condiments: " + cond.text)
    }
}

Спасибо

Ответ 1

Я не знаком с antixml, однако, поскольку другого ответа нет, я сделаю попытку

Только для записи ваш код возвращает

  mayo
  mustard

Точнее, строка начинается с пробелов/новой строки между концом и началом первого. Заготовки между майо и горчицей - это между двумя приправами, а пробелы после горчицы - до закрытия.

В antixml первое, что нужно сделать, похоже, преобразует ваш, что просто

val someAntiXml = someXML.anti

Получение части приправы легко:

var condiments = someAntiXml \ 'condiments

Затем нужно извлечь текст. Казалось, что способ сделать это был

condiments \\ text

Но \\ не перемещает структуру по порядку, это похоже на обход ширины. Как следствие, пробелы, которые находятся прямо под приправами, встречаются перед майо и горчицей, которые находятся на одном уровне ниже, в элементах.

Итак, вот возможная реализация для извлечения текста. Может быть, есть более стандартный способ, но я его не нашел.

def textOf(g: Group[Node]) : String = 
  g.toList.map{
    case Elem(_, _, _, _, children) => textOf(children) 
    case t: Text => t.text
    case c: CDATA => c.text 
    case _ => ""
  }.mkString

Тогда textOf(someAntiXml \ "condiments") дает ожидаемый результат.