使用MarkupBuilder构建xml文件时没有结束标记

时间:2018-01-09 10:46:56

标签: xml jenkins groovy jenkins-pipeline

我想在我的Jenkins-Pipeline-Job中使用Groovy来构建我的Jenkins Slaves和已安装节点的状态列表。因此我有一些列表应该以xml显示。使用IntelliJ进行测试时,我编写了以下代码。

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

只要我在IntelliJ中运行代码,一切正常,我得到一个有效的xml文件:

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

但是如果我在Jenkins实例上执行相同的脚本,则大多数结束标记都会丢失:

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

我做错了什么或者在通过jenkins创建xml文件时是否有特定的步骤?

3 个答案:

答案 0 :(得分:0)

这真的很奇怪。

您可以尝试以下内容,看看是否有帮助。

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)

答案 1 :(得分:0)

我明白了。我真的不明白为什么,但MarkupBuilder可以在@nonCPS标记的方法中进行封装。如果我调用这个方法,jenkins会按预期执行。

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

buildXml(list1, list2)

答案 2 :(得分:0)

使用函数nodeCompleted('','computers')可以解决此问题

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