Scala XML, Получить узлы, где родительский элемент имеет значение атрибута - PullRequest
5 голосов
/ 27 сентября 2011

Любой способ упростить следующее? или уменьшить код шаблона с другой функцией?

scala> val ns = <foo><bar id="1"><tag>one</tag><tag>uno</tag></bar><bar id="2"><tag>two</tag><tag>dos</tag></bar></foo>
ns: scala.xml.Elem = <foo><bar id="1"><tag>one</tag><tag>uno</tag></bar><bar id="2"><tag>two</tag><tag>dos</tag></bar></foo>

scala> (ns \\ "bar" filterNot{_ \\ "@id"  find { _.text == "1" } isEmpty}) \\ "tag"
res0: scala.xml.NodeSeq = NodeSeq(<tag>one</tag>, <tag>uno</tag>)

Ответы [ 2 ]

16 голосов
/ 28 сентября 2011

Я смог найти только незначительное улучшение, тест find / isEmpty можно заменить на exists:

(ns \\ "bar" filter { _ \\ "@id" exists (_.text == "1") }) \\ "tag"

Редактировать после уточняющего комментария:

Это действительно хорошая идея!Попробуйте это для размера:

import xml._

implicit def richNodeSeq(ns: NodeSeq) = new {

  def \@(attribMatch: (String, String => Boolean)): NodeSeq =
    ns filter { _ \\ ("@" + attribMatch._1) exists (s => attribMatch._2(s.text)) }

}

ns \\ "bar" \@ ("id", _ == "1") \\ "tag"

Я использовал предикат вместо жесткого сравнения значений атрибутов.

0 голосов
/ 13 августа 2018

Лучший способ - определить неявный класс:

   object XmlE {
    implicit class XmlE(val xml: NodeSeq) extends AnyVal {
         def \@(attr: (String, String => Boolean)): NodeSeq = {
             xml filter {
                _ \ ("@" + attr._1) exists (s => attr._2(s.text))
                         }
                    }
            }
   }

Затем использовать его из другого класса:

import XmlE._
.....
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...