Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Variable name collision in RewriteRule class #129

Closed
hghina0 opened this issue Jan 25, 2017 · 2 comments
Closed

Variable name collision in RewriteRule class #129

hghina0 opened this issue Jan 25, 2017 · 2 comments
Labels
Milestone

Comments

@hghina0
Copy link

hghina0 commented Jan 25, 2017

Below program doesn't give expected output

import scala.xml.{Elem, Node, Text}
import scala.xml.transform.{RewriteRule, RuleTransformer}

object XmlTransform extends App {
  val name = "contents"
  val value = "2"

  val InputXml : Node =
    <root>
      <subnode>1</subnode>
      <contents>1</contents>
    </root>

  val transformer = new RuleTransformer(new RewriteRule {
    override def transform(n: Node): Seq[Node] = n match {
      case elem @ Elem(prefix, label, attribs, scope, _) if elem.label == name =>
        Elem(prefix, label, attribs, scope, false, Text(value))

      case other => other
    }
  })
  println(transformer(InputXml))
}

If I change "case if" statement like

case elem @ Elem(prefix, label, attribs, scope, _) if elem.label == "contents" =>
        Elem(prefix, label, attribs, scope, false, Text(value))

It transforms xml as expected. Is it known issue?

@ashawley
Copy link
Member

Is it known issue?

No, probably not. You have come accross an unfortunate name-collision because of the lexical scoping rules of Scala. It's a sconsequence of this class member:

http://www.scala-lang.org/api/current/scala-xml/scala/xml/transform/RewriteRule.html#name:String

https://github.com/scala/scala-xml/blob/4c09977/src/main/scala/scala/xml/transform/RewriteRule.scala#L23

It's not clear what it's for, but there's probably no reason to have it there, IMO.

Here's a minimal version of your test

  @Test
  def rewriteRuleNameCollision = { // #129

    val name = "contents"

    val transformer = new RuleTransformer(new RewriteRule {
      override def transform(n: Node): Seq[Node] = n match {
        case elem @ Elem(prefix, label, attribs, scope, _) if elem.label == name =>
          Elem(prefix, label, attribs, scope, false, Text("2"))
        case _ => n
      }
    })
    assertEquals(<contents>2</contents>, transformer(<contents>1</contents>))
  }

It fails with

[error] Test scala.xml.Transformers.rewriteRuleNameCollision failed: expected:<<contents>2</contents>> but was:<<contents>1</contents>>

@hghina0
Copy link
Author

hghina0 commented Jan 25, 2017

Thanks for quick clarification. I appreciate.

@ashawley ashawley changed the title Runtime label matching inside RewriteRule fails Variable name collision in RewriteRule class Apr 13, 2018
@ashawley ashawley modified the milestones: 1.1.1, 1.2.0 Apr 13, 2018
@ashawley ashawley mentioned this issue Apr 5, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants