No closing tags while building xml file with MarkupBuilder

倾然丶 夕夏残阳落幕 提交于 2021-01-28 01:55:08

问题


I want to use Groovy in my Jenkins-Pipeline-Job to build a Statuslist of my Jenkins Slaves and the installed nodes. Therefore I have some lists which should be displayed in xml. While testing with IntelliJ i wrote the following code.

import groovy.xml.MarkupBuilder

def listNodeNames = []
listNodeNames << 'SLAVE1_NODE_1'
listNodeNames << 'SLAVE1_NODE_2'
listNodeNames << 'SLAVE2_NODE_1'
listNodeNames << 'SLAVE2_NODE_2'


def listComputerNames = []
listComputerNames << 'SLAVE1'
listComputerNames << 'SLAVE2'

def stringWriter = new StringWriter()
def xmlBuilder = new MarkupBuilder(stringWriter)

xmlBuilder.computers {
    for (i = 0; i < listComputerNames.size(); i++){

        xmlBuilder.computer {
            xmlBuilder.computerName("${listComputerNames[i]}")
            xmlBuilder.computerStatus("online")

            for (j = 0; j < listNodeNames.size(); j++){
                if (listNodeNames[j].contains(listComputerNames[i])){
                    xmlBuilder.slave {
                        xmlBuilder.slaveName("${listNodeNames[j]}")
                        xmlBuilder.slaveStatus('test')
                        xmlBuilder.slaveReason('test')
                    }
                }
            }
        }

    }
}

def xml = stringWriter.toString()
println xml

As long as i run the code in IntelliJ, everything works fine and i get a valid xml file:

  <computers>
      <computer>
        <computerName>SLAVE1</computerName>
        <computerStatus>online</computerStatus>
        <slave>
          <slaveName>SLAVE1_NODE1</slaveName>
          <slaveStatus>test</slaveStatus>
          <slaveReason>test</slaveReason>
        </slave>
        <slave>
          <slaveName>SLAVE1_NODE2</slaveName>
          <slaveStatus>test</slaveStatus>
          <slaveReason>test</slaveReason>
        </slave>
      </computer>
      <computer>
        <computerName>SLAVE2</computerName>
        <computerStatus>online</computerStatus>
        <slave>
          <slaveName>SLAVE2_NODE1</slaveName>
          <slaveStatus>test</slaveStatus>
          <slaveReason>test</slaveReason>
        </slave>
        <slave>
          <slaveName>SLAVE2_NODE2</slaveName>
          <slaveStatus>test</slaveStatus>
          <slaveReason>test</slaveReason>
        </slave>
      </computer>
    </computers>

But if i execute the same script on my Jenkins instance most closing tags are missing:

<computers>
  <computer>
    <computerName>SLAVE1</computerName>
    <computerStatus>online</computerStatus>
    <slave>
      <slaveName>SLAVE1_NODE1</slaveName>
      <slaveStatus>test</slaveStatus>
      <slaveReason>test</slaveReason>
      <slave>
        <slaveName>SLAVE1_NODE2</slaveName>
        <slaveStatus>test</slaveStatus>
        <slaveReason>test</slaveReason>
        <computer>
          <computerName>SLAVE2</computerName>
          <computerStatus>online</computerStatus>
          <slave>
            <slaveName>SLAVE2_NODE1</slaveName>
            <slaveStatus>test</slaveStatus>
            <slaveReason>test</slaveReason>
            <slave>
              <slaveName>SLAVE2_NODE2</slaveName>
              <slaveStatus>test</slaveStatus>
              <slaveReason>test</slaveReason>

Am i doing something wrong or are there specific steps to do while creating xml files via jenkins?


回答1:


I figured it out. I don't really understand why but the MarkupBuilderhast du be capsuled inside a @nonCPSmarked method. If I call this method jenkins performs as expected.

@nonCPS
def buildXml(list1, list2){
    //generate xml from lists
}

buildXml(list1, list2)



回答2:


That is really strange.

You may try below and see if that helps.

def listNodeNames = ['SLAVE1_NODE_1', 'SLAVE1_NODE_2', 'SLAVE2_NODE_1', 'SLAVE2_NODE_2']

def listComputerNames = ['SLAVE1', 'SLAVE2']

def xml = new groovy.xml.StreamingMarkupBuilder().bind {
    computers {
      listComputerNames.collect { cn ->
          computer {
             computerName(cn)
             computerStatus('online')
             listNodeNames.collect { slv ->
                if (slv.startsWith(cn)){
                   slave {
                     slaveName(slv)
                     slaveStatus('test')
                     slaveReason('test')
                   }
                }
             }
          }
      }
    }
}

println groovy.xml.XmlUtil.serialize(xml)



回答3:


Use function nodeCompleted('','computers') which will fix this issue

import groovy.xml.MarkupBuilder

def listNodeNames = []
listNodeNames << 'SLAVE1_NODE_1'
listNodeNames << 'SLAVE1_NODE_2'
listNodeNames << 'SLAVE2_NODE_1'
listNodeNames << 'SLAVE2_NODE_2'


def listComputerNames = []
listComputerNames << 'SLAVE1'
listComputerNames << 'SLAVE2'

def stringWriter = new StringWriter()
def xmlBuilder = new MarkupBuilder(stringWriter)

xmlBuilder.computers {
    for (i = 0; i < listComputerNames.size(); i++){

        xmlBuilder.computer {
            xmlBuilder.computerName("${listComputerNames[i]}")
            xmlBuilder.computerStatus("online")

            for (j = 0; j < listNodeNames.size(); j++){
                if (listNodeNames[j].contains(listComputerNames[i])){
                    xmlBuilder.slave {
                        xmlBuilder.slaveName("${listNodeNames[j]}")
                        xmlBuilder.slaveStatus('test')
                        xmlBuilder.slaveReason('test')
                    }
                    nodeCompleted('computers','slave')
                }
            }
        }
        nodeCompleted('','computers')

    }
}

def xml = stringWriter.toString()
println xml


来源:https://stackoverflow.com/questions/48166449/no-closing-tags-while-building-xml-file-with-markupbuilder

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!