Skip to Content
Technical Articles
Author's profile photo Fatih Pense

Groovy EDI Segment Counter (also known as $B2B_SEG_COUNTER)

EDIFACT messages require a total segment count in the segment UNT. X12 messages require the same information in segment SE data element 96.

In SAP Process Integration/Orchestration(PI/PO) this requirement was handled by mapping the constant $B2B_SEG_COUNTER to the relevant field. SAP Cloud Integration doesn’t have this feature yet, but we can create a Groovy script that replicates exactly the same behavior.

You can put this script just before the “XML to EDI converter” step, or after “EDIFACT Post-processing” step. It is flexible and it can be used when the message body has the XML root element starting with M_, or the root element is Interchange.

You can map $B2B_SEG_COUNTER to any field. You can use the constant function in Integration Advisor.



Note that groovy.util.Node returns String in Groovy IDE and a QName object in Cloud Integration. This behavior is flexible in the Groovy spec. “getLocalName” function handles this difference.

import java.util.HashMap;

def Message processData(Message message) {

    String magicKeyword = '$B2B_SEG_COUNTER'

    def body = message.getBody(
    def parser = new XmlParser()
    def ediXmlDoc = parser.parse(body)
    Integer segmentCount = 0

    //find message and count segments inside
    ediXmlDoc.breadthFirst().findAll { possibleMessageNode ->
        // GroovyIDE returns String, Cloud Integration returns QName here.
        // println
        // The implementation is flexible in the Class spec. .name() function returns java.lang.Object. 
        // It is possible that since this input has no namespace, it returns string.

        // it is a message node
        if ( getLocalName(possibleMessageNode).startsWith("M_") ){
            possibleMessageNode.breadthFirst().findAll { possibleSegmentNode -> 
                // it is a segment node
                if ( getLocalName(possibleSegmentNode).startsWith("S_") ){
                    // println
                    segmentCount ++

    // find nodes to be filled
    ediXmlDoc.breadthFirst().findAll { node ->
        if (node.localText().size() > 0 && node.localText().first() == magicKeyword ){
           node.value = segmentCount

    // Write document to body
    def sw = new StringWriter()
    def xmlNodePrinter = new XmlNodePrinter(new PrintWriter(sw))
    xmlNodePrinter.with {
        preserveWhitespace = true

    String result = sw.toString()

    return message;

def String getLocalName( groovy.util.Node node ){
    def name = // can be java.lang.String or groovy.xml.QName or another object!
    String localName = ""
    if (name instanceof groovy.xml.QName) {
        groovy.xml.QName qname = (groovy.xml.QName) name
        localName = qname.getLocalPart()
    else {
        localName = name.toString()
    return localName


GitHub Repository for Contributions

You can see this example & others at the GitHub repository. You can star⭐ the project or even watch👀 for all future updates!

Contributions are welcome! I can help with the description or the code if you want.


Related Blog Posts

This blog post by Vikas Kumar Singh shares the XSLT version of a similar solution. You should use it before the “Envelope Handling” step.


Assigned Tags

      You must be Logged on to comment or reply to a post.
      Author's profile photo Robert Jancich
      Robert Jancich

      Hello Fatih Pense ,

      thank you for this hint. Actually I tried payload which also contained empty tags e.g. <PRI/> so with additional check the count fits nicely.

      if (possibleSegmentNode.value() != []) {
      segmentCount ++




      Author's profile photo Fatih Pense
      Fatih Pense
      Blog Post Author

      Thank you for the improvement Robert!


      Author's profile photo Young Soo Kim
      Young Soo Kim

      Hi Faith Pense


      Would you able to provide for CNT segment on D_6066 field for calculating line items on DESADV edifact ? I was posted and questioned for that matter on SCN.

      -How to populate segment CNT from EDIFACT in SAP CPI MAG or XSLT | SAP Community

      Is it possible to get line-item count function on MAG or XSLT or Groovy needs same as above additional development?

      All the Best