且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

Groovy:将 XML 节点附加到现有的 XML 文档

更新时间:2022-03-24 17:38:54

给定 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