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

XML parser reverses attribute order #6341

Closed
scabug opened this issue Sep 8, 2012 · 5 comments
Closed

XML parser reverses attribute order #6341

scabug opened this issue Sep 8, 2012 · 5 comments

Comments

@scabug
Copy link

scabug commented Sep 8, 2012

When parsing XML and then writing it out again, the order of attributes is reversed.

This prevents certain use cases where one wants to modify an XML file and have a minimal amount of changes. E.g. adding a new element to a file causes all existing attributes to get reversed.

The cause is here:

https://github.com/scala/scala/blob/81e3121eb09010375783d13e8c4c853686a34ffd/src/library/scala/xml/parsing/MarkupParser.scala#L302

aMap: MetaData is built by prepending new attributes to the linked list, causing the reversal.

The attached patch adds a failing test case. (It failed when I wrote it originally, now I can't test it because the build fails).

@scabug
Copy link
Author

scabug commented Sep 8, 2012

Imported From: https://issues.scala-lang.org/browse/SI-6341?orig=1
Reporter: robinst
Affected Versions: 2.10.0-M7
Attachments:

@scabug
Copy link
Author

scabug commented Sep 9, 2012

@som-snytt said:
This is a duplicate of #3441 and #2735, except that there are a few different parsers at issue: the compiler's MarkupParser for literals, the library's MarkupParser, and the utility methods that use xerces, IIUC.

  def main(args: Array[String]): Unit = {
    val input = """<elem one="test" two="test2" three="test3"></elem>"""
    val doc = XML.loadString(input)
    println(doc)
    
    val cpa = ConstructingParser.fromSource(io.Source.fromString(input), preserveWS = true)
    val cpadoc = cpa.document()
    val ppr = new PrettyPrinter(80,5)
    println(ppr.format(cpadoc.docElem))
  }

I remember this issue from the first Scala code I ever wrote, but I haven't used XML since then, so bear with me. My solution was a hook in PrettyPrinter for formatting attributes:

      // in leafTag and startTag; but also Utility.toXML/serialize
      //n.attributes buildString sb
      formatAttributes(n, sb)

I realize now this was my first fold ever:

  override protected def formatAttributes(n: Node, sb: StringBuilder) {
    //n.attributes.toList.reverse.foldLeft(sb) { (a,b) => a.append(' '); b.toString1(a); a }
    (sb /: n.attributes.toList.reverse) { (r,v) => r.append(' '); v.toString1(r); r }
  }

And maybe the last time I used /: except as an emoticon. I see toString1 is protected now, so cut/paste that, too. I don't know if such a formatAttributes hook is worth it?

@scabug
Copy link
Author

scabug commented Sep 14, 2012

robinst said:
Yes, this is about the library's MarkupParser, see description. #2735 was about the compiler's literal parser, so this is not a duplicate. But it's a similar issue.

The above is merely a workaround, but thanks anyway.

It should really be fixed so that round-tripping does not change things around needlessly.

@scabug
Copy link
Author

scabug commented Jul 17, 2015

@SethTisue said:
The scala-xml library is now community-maintained. Issues with it are now tracked at https://github.com/scala/scala-xml/issues instead of here in the Scala JIRA.

Interested community members: if you consider this issue significant, feel free to open a new issue for it on GitHub, with links in both directions.

@scabug scabug closed this as completed Jul 17, 2015
@scabug
Copy link
Author

scabug commented Jul 23, 2015

Graeme Phillipson (cogpp) said:
I have raised a copy of this in the new space as scala/scala-xml#65

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant