Skip to content

How would I focus on only the instances of an element which have a particular attribute value? #38

Open
@howyp

Description

@howyp

This lib looks great!

But I'm a bit stuck on how to do something that I'd expected to be straight forward. Maybe I just don't know enough about optics. What I want is to select only the elements that have an attribute with a given value.

So given this example:

val xml =
  """
    |<a>
    |  <b>
    |    <c example="1">1234</c>
    |    <c example="2">5678</c>
    |    <c example="3">9123</c>
    |  </b>
    |</a>
  """.stripMargin

I'd be after only the <c> that has a example attribute with value 2. Using this expression gives me all of the <c> elements:

val c = root \ "b" \ "c"
println(pl.msitko.xml.parsing.XmlParser.parse(xml).map(c.getAll))

//prints:
//Right(List(Element(Vector(Attribute(ResolvedName(,,example),1)),List(Text(1234)),Vector()), Element(Vector(Attribute(ResolvedName(,,example),2)),List(Text(5678)),Vector()), Element(Vector(Attribute(ResolvedName(,,example),3)),List(Text(9123)),Vector())))

I've tried using having, something like this:

val c = root \ "b" \ "c" having {
  case LabeledElement(_, Element(attr, _, _)) => attr.find(_.key.localName == "example").exists(_.value == "1")
}

but that seems to only pass child elements of <c> to the partial function, which doesn't give me a chance to inspect the attributes.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions