我看到了下面的例子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"))
但是,这是行不通的。 我知道我可以使用模式匹配,只是想看看,如果我可以做一些魔术过滤。
干杯 - 埃德
首先,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
”,从而结束了相当难看。
在这个问题的代码段不使用Scala 2.8的工作 - 因为这比较讨论
(_ == value)
需要与被替换
(_.text == value)
或
(_ == Text(value))
或从字符串值到文本变型。
而在丹尼尔的回答(_.value == value)
需要被替换(_.value.text == value)
。
以前的解决方案并没有为我工作,因为他们都找任何匹配值。 如果你想寻找一个值的特定属性,这里是我的解决方案:
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"
我是很新的斯卡拉,我建议你这个解决办法,但我不知道这是最好的一个:
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>)
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