发现有匹配使用Scala一定值的属性的所有节点(Find all nodes that have a

2019-08-16 19:58发布

我看到了下面的例子Nabble ,这里的目标是返回包含与包含值Y X的ID属性的所有节点:

//find all nodes with an attribute "class" that contains the value "test"
val xml = XML.loadString( """<div>
<span class="test">hello</span>
<div class="test"><p>hello</p></div>
</div>""" )

def attributeEquals(name: String, value: String)(node: Node) = 
{ 
    node.attribute(name).filter(_==value).isDefined
}

val testResults = (xml \\ "_").filter(attributeEquals("class","test")) 
//prints: ArrayBuffer(
//<span class="test">hello</span>, 
//<div class="test"><p>hello</p></div>
//) 
println("testResults: " + testResults ) 

作为扩展到这个怎么会一个执行以下操作:查找包含包含y的值的任何属性的所有节点:

//find all nodes with any attribute that contains the value "test"
val xml = XML.loadString( """<div>
 <span class="test">hello</span>
 <div id="test"><p>hello</p></div>
 <random any="test"/></div>""" )
 //should return: ArrayBuffer(
 //<span class="test">hello</span>, 
 //<div id="test"><p>hello</p></div>, 
 //<random any="test"/> )

我想我可以使用_像这样:

val testResults = (xml \\ "_").filter(attributeEquals("_","test")) 

但是,这是行不通的。 我知道我可以使用模式匹配,只是想看看,如果我可以做一些魔术过滤。

干杯 - 埃德

Answer 1:

首先,XML是Scala中文字,所以:

val xml = <div><span class="test">hello</span><div class="test"><p>hello</p></div></div>

现在,这个问题:

def attributeValueEquals(value: String)(node: Node) = {
     node.attributes.exists(_.value.text == value)
}

事实上,我曾用“ exists ”而不是“ filter ”和“ defined ”为原问题为好。

最后,我个人更喜欢操作风格的语法,特别是当你有一个现成的功能,而不是匿名一个,传递给“ filter ”:

val testResults = xml \\ "_" filter attributeValueEquals("test")

原来的混合操作风格为“ \\ ”和点阵风格的“ filter ”,从而结束了相当难看。



Answer 2:

在这个问题的代码段不使用Scala 2.8的工作 - 因为这比较讨论

 (_ == value) 
需要与被替换(_.text == value)(_ == Text(value))或从字符串值到文本变型。

而在丹尼尔的回答(_.value == value)需要被替换(_.value.text == value)



Answer 3:

以前的解决方案并没有为我工作,因为他们都找任何匹配值。 如果你想寻找一个值的特定属性,这里是我的解决方案:

def getByAtt(e: Elem, att: String, value: String) = {
    def filterAtribute(node: Node, att: String, value: String) =  (node \ ("@" + att)).text == value   
    e \\ "_" filter { n=> filterAtribute(n, att, value)} 
}

然后

getByAtt(xml, "class", "test")

这将区分class="test""notclass="test"



Answer 4:

我是很新的斯卡拉,我建议你这个解决办法,但我不知道这是最好的一个:

def attributeValueEquals(value: String)(node: Node) = {
  node.attributes.foldLeft(false)((a : Boolean, x : MetaData) => a | (x.value == value))
}

val testResults = (xml \\ "_").filter(attributeValueEquals("test")) 
println("testResults: " + testResults )

// prints: testResults: ArrayBuffer(<span class="test">hello</span>, 
// <div id="test"><p>hello</p></div>, 
// <random any="test"></random>)


Answer 5:

def nodeHasValue(node:Node,value:String) = node.attributes.value != null && node.attributes.value.contains(value)

(x \\ "_").filter( nodeHasValue(_,"test"))


文章来源: Find all nodes that have an attribute that matches a certain value with scala