Groovy:将 XML 节点附加到现有的 XML 文档 [英] Groovy: append an XML Node to an existing XML document
问题描述
我正在使用 Groovy 并尝试将 xml 节点插入到使用 XmlSlurper 解析的 xml 文档中.我设法在文档末尾添加了节点,但没有在我真正需要的地方添加.
I'm using Groovy and I'm trying to insert an xml node into a xml document parsed with XmlSlurper. I manage to add the node at the end of the document but not where I really need to.
原始文档:
<xml-fragment xmlns:ser="http://www.bea.com/wli/sb/services" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:con="http://www.bea.com/wli/sb/pipeline/config">
<ser:coreEntry isProxy="true" isEnabled="true" isTracingEnabled="false">
<ser:binding type="SOAP" isSoap12="false" xsi:type="con:SoapBindingType" xmlns:con="http://www.bea.com/wli/sb/services/bindings/config">
<con:wsdl ref="bus/src/main/osb/interfaces/apilink/ChargeServices"/>
<con:port>
<con:name>ChargeServicesPort</con:name>
<con:namespace>java:dk.tdc.apilink.logic.sessions.interfaces</con:namespace>
</con:port>
<con:selector type="SOAP body"/>
</ser:binding>
</ser:coreEntry>
</xml-fragment>
要添加的片段
def fragmentToAddXml = '''
<ser:security xmlns:ser="http://www.bea.com/wli/sb/services" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:con="http://www.bea.com/wli/sb/pipeline/config">hello</ser:security>
'''
这是我正在使用的代码.
This is the code I'm using.
def root = new XmlSlurper().parseText(file.getText())
root.'core-entry'.appendNode( fragmentToAddXml )
def xmlBuilder = new groovy.xml.StreamingMarkupBuilder().bind{ mkp.yield root }
请注意,新节点应置于ser:binding"节点之前.
Please note that the new node should be placed before the "ser:binding" node.
结果应该是:
<xml-fragment xmlns:ser="http://www.bea.com/wli/sb/services" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:con="http://www.bea.com/wli/sb/pipeline/config">
<ser:coreEntry isProxy="true" isEnabled="true" isTracingEnabled="false">
<ser:security xmlns:ser="http://www.bea.com/wli/sb/services" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:con="http://www.bea.com/wli/sb/pipeline/config">hello</ser:security>
<ser:binding type="SOAP" isSoap12="false" xsi:type="con:SoapBindingType" xmlns:con="http://www.bea.com/wli/sb/services/bindings/config">
<con:wsdl ref="bus/src/main/osb/interfaces/apilink/ChargeServices"/>
<con:port>
<con:name>ChargeServicesPort</con:name>
<con:namespace>java:dk.tdc.apilink.logic.sessions.interfaces</con:namespace>
</con:port>
<con:selector type="SOAP body"/>
</ser:binding>
</ser:coreEntry>
</xml-fragment>
谢谢
卢西亚诺
推荐答案
给定 xml(在字符串中用于测试)
Given the xml (in a string for testing)
def xml = '''<xml-fragment xmlns:ser="http://www.bea.com/wli/sb/services" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:con="http://www.bea.com/wli/sb/pipeline/config">
<ser:coreEntry isProxy="true" isEnabled="true" isTracingEnabled="false">
<ser:binding type="SOAP" isSoap12="false" xsi:type="con:SoapBindingType" xmlns:con="http://www.bea.com/wli/sb/services/bindings/config">
<con:wsdl ref="bus/src/main/osb/interfaces/apilink/ChargeServices"/>
<con:port>
<con:name>ChargeServicesPort</con:name>
<con:namespace>java:dk.tdc.apilink.logic.sessions.interfaces</con:namespace>
</con:port>
<con:selector type="SOAP body"/>
</ser:binding>
</ser:coreEntry>
</xml-fragment>'''
以及您要添加的 xml:
And the xml you want to add as:
def toadd = '''<ser:security xmlns:ser="http://www.bea.com/wli/sb/services" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:con="http://www.bea.com/wli/sb/pipeline/config">
hello
</ser:security>'''
然后你可以解析它们(通过第二个 true
参数将 XmlSlurper
设置为使用命名空间)
Then you can parse them both (with XmlSlurper
set to use namespaces via the 2nd true
parameter)
def root = new XmlSlurper( false, true ).parseText( xml )
fragmentToAdd = new XmlSlurper( false, true ).parseText( toadd )
附加 xml 以添加到 data
节点(如您想要的那样在 data
中,而不是 lastname
)
Append the xml to add to the data
node (as you want it inside data
, not lastname
)
root.coreEntry.appendNode( fragmentToAdd )
然后打印出来:
String outxml = groovy.xml.XmlUtil.serialize( root )
println outxml
打印:
<?xml version="1.0" encoding="UTF-8"?>
<xml-fragment>
<ser:coreEntry xmlns:ser="http://www.bea.com/wli/sb/services" isTracingEnabled="false" isProxy="true" isEnabled="true">
<ser:binding xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" isSoap12="false" xsi:type="SOAP">
<con:wsdl xmlns:con="http://www.bea.com/wli/sb/services/bindings/config" ref="bus/src/main/osb/interfaces/apilink/ChargeServices"/>
<con:port xmlns:con="http://www.bea.com/wli/sb/services/bindings/config">
<con:name>ChargeServicesPort</con:name>
<con:namespace>java:dk.tdc.apilink.logic.sessions.interfaces</con:namespace>
</con:port>
<con:selector xmlns:con="http://www.bea.com/wli/sb/services/bindings/config" type="SOAP body"/>
</ser:binding>
<ser:security>
hello
</ser:security>
</ser:coreEntry>
</xml-fragment>
我认为这是正确的(不是我想要的 100% 格式,而是正确的);-)
Which I believe is correct (not formatted 100% as I'd like, but correct) ;-)
如果顺序很重要,你可以像这样使用XmlParser
:
If order is important, you can use XmlParser
like so:
def root = new XmlParser( false, true ).parseText( xml )
fragmentToAdd = new XmlParser( false, true ).parseText( toadd )
// Insert this new node at position 0 in the children of the first coreEntry node
root.find { it.name() == 'ser:coreEntry' }.children().add( 0, fragmentToAdd )
String outxml = groovy.xml.XmlUtil.serialize( root )
println outxml
这篇关于Groovy:将 XML 节点附加到现有的 XML 文档的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!