Skip to content

Nodes with the same value are mixed up #63

@Leonti

Description

@Leonti

Hi!
I'm having a weird issue with targeting nodes that I want to replace, given the following snippet:

import scala.xml._
import advxml.syntax.traverse.try_._
import advxml.syntax.transform._
import advxml.instances.transform._
import scala.util._
import cats.implicits._

val doc = XML.loadString("""
<charts>
  <chart>
    <title>chart-0</title>
    <entries>
      <entry idx="0">
        <v>13</v>
      </entry>
    </entries>
  </chart>
  <chart>
    <title>chart-1</title>
    <entries>
      <entry idx="0">
        <v>12</v>
      </entry>
    </entries>
  </chart>  
</charts>
""")

def toEntries(root: NodeSeq): NodeSeq = (root \ "chart" filter hasImmediateChild("title", text(_ == "chart-1"))) \ "entries"

val rule = $(r => (toEntries(r) \ "entry" filter attrs("idx" -> (_ == "0"))) \ "v" ) ==> Replace(_ => <v>11</v>) 

val result: Try[NodeSeq] = doc.transform[Try](rule)

println(result.toOption.get)

It will output this:

<charts>
   <chart>
      <title>chart-0</title>
      <entries>
         <entry idx="0">
            <v>13</v>
         </entry>
      </entries>
   </chart>
   <chart>
      <title>chart-1</title>
      <entries>
         <entry idx="0">
            <v>11</v>
         </entry>
      </entries>
   </chart>
</charts>

https://scastie.scala-lang.org/JRM25U76S6yXpcIV6ZuDug
It correctly found entries of a chart which has chart-1 as a title and then replaced it.

But as soon as I make the original values to be the same number:

val doc = XML.loadString("""
<charts>
  <chart>
    <title>chart-0</title>
    <entries>
      <entry idx="0">
        <v>12</v>
      </entry>
    </entries>
  </chart>
  <chart>
    <title>chart-1</title>
    <entries>
      <entry idx="0">
        <v>12</v>
      </entry>
    </entries>
  </chart>  
</charts>
""")

it will replace the entry under chart-0, not chart-1 as expected:

<charts>
   <chart>
      <title>chart-0</title>
      <entries>
         <entry idx="0">
            <v>11</v>
         </entry>
      </entries>
   </chart>
   <chart>
      <title>chart-1</title>
      <entries>
         <entry idx="0">
            <v>12</v>
         </entry>
      </entries>
   </chart>
</charts>

https://scastie.scala-lang.org/KBkU87D6T4GhNlkDq3rWjQ

Looks like it's finding the element first, so in this case <v>12</v> and then using it for replacement, so if you have 2 identical elements bu with different paths it will replace the first one.

Or maybe I'm not using it correctly?
By they way, apart from this issue the library is a joy to use, thanks!

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions