scala 使用scala查找具有与特定值匹配的属性的所有节点
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1477215/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Find all nodes that have an attribute that matches a certain value with scala
提问by ed.
I saw the following example on Nabble, where the goal was to return all nodes that contain an attribute with an id of X that contains a value Y:
我在Nabble上看到了以下示例,其中的目标是返回所有节点,这些节点包含一个 id 为 X 且包含值 Y 的属性:
//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 )
As an extension to this how would one do the following: Find all nodes that contain any attribute that contains a value of Y:
作为对此的扩展,您将如何执行以下操作:查找包含任何包含 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"/> )
I was thinking I could use a _ like so:
我在想我可以像这样使用 _ :
val testResults = (xml \ "_").filter(attributeEquals("_","test"))
But it doesn't work. I know I can use pattern matching, but just wanted to see if I could do some magic with the filtering.
但它不起作用。我知道我可以使用模式匹配,但只是想看看我是否可以用过滤做一些魔术。
Cheers - Ed
干杯 - 埃德
回答by Daniel C. Sobral
First, XML are literals in Scala, so:
首先,XML 在 Scala 中是文字,所以:
val xml = <div><span class="test">hello</span><div class="test"><p>hello</p></div></div>
Now, as to the problem:
现在,至于问题:
def attributeValueEquals(value: String)(node: Node) = {
node.attributes.exists(_.value.text == value)
}
In fact, I'd have used "exists" instead of "filter" and "defined" for the original problem as well.
事实上,对于原始问题,我也会使用“ exists”而不是“ filter”和“ defined”。
Finally, I personally prefer operator style syntax, particularly when you have a ready function, instead of an anonymous one, to pass to "filter":
最后,我个人更喜欢操作符风格的语法,特别是当你有一个准备好的函数而不是匿名函数传递给“ filter”时:
val testResults = xml \ "_" filter attributeValueEquals("test")
The original mixes operator style for "\\" and dot style for "filter", which ends up quite ugly.
原始混合了“ \\”的操作符样式和“ ”的点样式filter,结果非常丑陋。
回答by Dmitry Stropalov
Code snippet in the question doesn't working with Scala 2.8 - due to this comparasion
问题中的代码片段不适用于 Scala 2.8 - 由于这种比较
(_ == value)需要被替换(_.text == value)(_.text == value)或(_ == Text(value))(_ == Text(value))或字符串文本改变类型的值。And in Daniel's answer (_.value == value)needs to be replaced with (_.value.text == value).
在丹尼尔的回答中(_.value == value)需要替换为(_.value.text == value).
回答by user1003751
The previous solutions didn't work for me because they all look for anyvalue that matches. If you want to look for a particularattribute with a value, here is my solution:
以前的解决方案对我不起作用,因为它们都在寻找任何匹配的值。如果要查找具有值的特定属性,这是我的解决方案:
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)}
}
And then
接着
getByAtt(xml, "class", "test")
This will differentiate between class="test"and "notclass="test"
这将区分class="test"和"notclass="test"
回答by Maxime
I'm quite new to Scala, I propose you this solution, but I'm not sure this is the best one:
我对 Scala 很陌生,我向您推荐了这个解决方案,但我不确定这是最好的:
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>)
回答by Germán
def nodeHasValue(node:Node,value:String) = node.attributes.value != null && node.attributes.value.contains(value)
(x \ "_").filter( nodeHasValue(_,"test"))

