Find all nodes that have an attribute that matches a certain value with scala

前端 未结 5 1042
遥遥无期
遥遥无期 2021-02-08 04:00

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:

//find all nodes         


        
相关标签:
5条回答
  • 2021-02-08 04:27
    def nodeHasValue(node:Node,value:String) = node.attributes.value != null && node.attributes.value.contains(value)
    
    (x \\ "_").filter( nodeHasValue(_,"test"))
    
    0 讨论(0)
  • 2021-02-08 04:29

    Code snippet in the question doesn't working with Scala 2.8 - due to this comparasion

    (_ == value)
    Needs to be replaced with (_.text == value) or (_ == Text(value)) or change type of value from String to Text.

    And in Daniel's answer (_.value == value) needs to be replaced with (_.value.text == value).

    0 讨论(0)
  • 2021-02-08 04:38

    First, XML are literals in Scala, so:

    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.

    Finally, I personally prefer operator style syntax, particularly when you have a ready function, instead of an anonymous one, to pass to "filter":

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

    The original mixes operator style for "\\" and dot style for "filter", which ends up quite ugly.

    0 讨论(0)
  • 2021-02-08 04:47

    The previous solutions didn't work for me because they all look for any value that matches. If you want to look for a particular attribute 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"

    0 讨论(0)
  • 2021-02-08 04:47

    I'm quite new to Scala, I propose you this solution, but I'm not sure this is the best one:

    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>)
    
    0 讨论(0)
提交回复
热议问题