问题
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 MarkupBuilder
hast du be capsuled inside a @nonCPS
marked 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