groovy - xml - 保留属性顺序

时间:2012-04-02 14:57:30

标签: xml groovy

我需要打印我使用groovy操作的XML并维护属性顺序。我不在乎它是否使用XmlParser / XmlNodePrinter或XmlSlurper / StreamingMarkupBuilder。我目前的代码如下:

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)

这是送入程序的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>

但是,在我打印出修改过的文件之后,接口和实现属性是相反的。

我已经知道你在想什么:xml属性顺序无关紧要。好吧,我的老板的要求是保留属性顺序b / c它已经这么久了。我实际上应该使用Java / DOM4J编写这个解析器,我试图向我的团队展示一些新东西。任何帮助,将不胜感激。谢谢!

1 个答案:

答案 0 :(得分:2)

如果不编写自己的代码来输出XML,我认为这是不可能的。

SAX解析器没有属性排序的概念(AFAIK),因此在XmlSlurper甚至看到数据之前订单将丢失......我找到了一个thread on the groovy-user list,其中讨论了这个,但它似乎没有提出任何解决方案......

认为可以XmlParser,因为它似乎维持秩序:

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

打印:

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

乍一看似乎没错?