我需要打印我使用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编写这个解析器,我试图向我的团队展示一些新东西。任何帮助,将不胜感激。谢谢!
答案 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>
乍一看似乎没错?