Groovy - xml - preserve order of attributes

I need to print the XML I have manipulated using groovy and maintain the order of the attributes. I don't care if it uses XmlParser / XmlNodePrinter or XmlSlurper / StreamingMarkupBuilder. My current code looks like this:

File file = new File('input.xml')
def root = new XmlSlurper().parse(file)

def admins = root.user.findAll {it.@role.text().equals("admin")}
admins.each { admin ->
  admin.permission.findAll { it.@interface.text().equals("RoleManagement") 
  }.each {
    it.@implementation = "AdminRoleManagement"
  }
}

def smb = new StreamingMarkupBuilder().bind { mkp.yield root }
new File('output.xml').text = groovy.xml.XmlUtil.serialize(smb)

      

Here's the XML that's loaded into the program

<users>
  <user username="test1234" role="admin">
    <permission interface="com.test.RoleManagement" implementation="com.test.AdminRoleManagement"/>
    <permission interface="com.test.UserAdministration" implementation="com.test.UserAdministrationImpl"/>
  </user>
</users>

      

After I print the modified file, the interface and implementation attributes are canceled.

I already know what you're thinking: the order of the xml attributes doesn't matter. Well, my requirement from my boss is to keep the order of the b / c attributes that's been this way for ages. Actually I had to write this parser using Java / DOM4J and I was trying to show my team something new. Any help would be greatly appreciated. Thank!

+3


source to share


1 answer


I don't think this is possible without writing your own code to output the XML.

The SAX parser has no concept of attribute ordering (AFAIK) and so the order will be lost before it XmlSlurper

even sees the data ... I found groovy -user in the list discussing this, but it doesn't seem to fit any decisions ...

I think this is possible with the help XmlParser

as it looks like the order:

def xml = '''<users>
            |  <user username="test1234" role="admin">
            |    <permission interface="com.test.RoleManagement" implementation="com.test.AdminRoleManagement"/>
            |    <permission interface="com.test.UserAdministration" implementation="com.test.UserAdministrationImpl"/>
            |  </user>
            |</users>'''.stripMargin()

def root = new XmlParser().parseText( xml )

def admins = root.user.findAll { it.@role == "admin" }

admins.each { admin ->
  admin.permission.findAll {
    it.@interface == "com.test.RoleManagement" 
  }.each {
    it.@implementation = "AdminRoleManagement"
  }
}

String output = new StringWriter().with { sw ->
  new XmlNodePrinter( new PrintWriter( sw ) ).print( root )
  sw.toString()
}
println output

      



What prints:

<users>
  <user username="test1234" role="admin">
    <permission interface="com.test.RoleManagement" implementation="AdminRoleManagement"/>
    <permission interface="com.test.UserAdministration" implementation="com.test.UserAdministrationImpl"/>
  </user>
</users>

      

Seems right at first glance?

+2


source







All Articles