Groovy - XML - 保留属性顺序

3

我需要打印使用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 属性顺序并不重要。但是,我的老板要求保留属性顺序,因为这样做已经很长时间了。实际上,我本来应该使用 Java/DOM4J 编写此解析器,但我想向团队展示一些新东西。感谢任何帮助!


你能否提供一些包含问题的示例XML代码,以便放入问题描述中? - tim_yates
添加了一些示例 XML - 谢谢 - jeff
1个回答

2
我认为在不编写自己的代码输出XML的情况下是不可能实现的。
据我所知,SAX解析器没有属性排序的概念,因此顺序将在XmlSlurper看到数据之前丢失... 我在groovy-user列表中找到了一篇讨论此问题的帖子,但似乎没有提出任何解决方案...
我认为使用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>

一开始看起来似乎是正确的?


是的,我看到了。也许我希望有一种方法可以在另一侧(打印期间)格式化数据。感谢您的评论。 - jeff
哇 - 我真是个白痴。我尝试过了,但那时我已经使用XmlSlurper/StreamingMarkupBuilder覆盖了我的文件,它没有保留顺序。这对我很有用。谢谢Tim,你太棒了 - 今天是你第二次帮助我。 - jeff
1
@jeff 很高兴能帮忙 :-) 祝你好运,希望老板会喜欢 ;-) - tim_yates
示例的XML解析器代码在Groovy 1.8或2.2中无法工作。更改没有反映在输出中 - com.test.AdminRoleManagement应该被替换为AdminRoleManagement。 - seanf

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接