ibm-doors

Doors DXL how to read and parse a CSV file?


I have a CSV file with only two columns that I would like to parse out. The first column of the CSV file is the absolute ID of an object in one (source) module and the second column is the absolute ID of an object in another (destination) module. I will be using the data entries to create DOORS links via DXL.

How do I parse the CSV file in a DOORS DXL language so that I can use the information in my script?


Solution

  • As a giveaway of the day and since I did not find a solution online, use this file & functions to get you started.

    // Support import of information from CSV files
    /*
     * Support import of information from CSV files
     * 
     * V:\Development\includes\CSVFileImport.inc
     *
     * Revision History:
     * Version 0.0
     * Created on: 2008-04-16 11:31:15
     * Created by: Ruediger Kaffenberger, TKRE (ruediger.kaffenberger@muc.mtu.com)
     *
     */
    
    XFLAGS_ &= ~AutoDeclare_
    
    void updateModuleAttriutes(Module)
    /*******************************************************************************
     * Global Variables
     */
    
    int     nRow
    Stream  stCSV
    Skip    skColumnHeaders       = null
    int     nColumn
    Skip    skRowData     = null
    
    const Regexp  reQuotes1
    const Regexp  reQuotes2
    const   Regexp  reAnything  = regexp ".*"
    
    char    cDoubleQuote   = '\"'
    
    Buffer  bWork = null
    
    /*******************************************************************************
     * impSprRemoveDoubleQuotes
     *
     */
    
    string impSprRemoveDoubleQuotes(Buffer buff) {
        Buffer temp
        string result
        int    i        = 0
        int    buff_len = length buff
        bool   found    = false
    
        if (buff_len == 0)
            return ""
    
        temp = create()
    
        if (buff[0] == cDoubleQuote)
            i++
    
        while (i < buff_len) {
            if (buff[i] == cDoubleQuote) {
                if (found) {
                    found = false
                } else {
                    temp += buff[i]
                    found = true
                }
            } else {
                temp += buff[i]
            }
            i++
        }
    
    
        buff_len = length temp
        if (temp[buff_len - 1] == cDoubleQuote)
            result = temp[0:buff_len - 2] ""
        else
            result = temp[0:buff_len - 3] ""
    
        delete temp
    
        return result
    
    } /* impSprRemoveDoubleQuotes */
    
    
    /*******************************************************************************
     * impSprHasEvenNumDoubleQuotes
     *
     */
    
    bool impSprHasEvenNumDoubleQuotes(Buffer buff) {
        int    i     = 0
        int    count = 0
    
        if (length buff == 0)
            return false
    
        while (i < length buff) {
            if (buff[i] == cDoubleQuote)
                count++
            i++
        }
    
        if (count%2 == 0)
            return true
        else
            return false
    
    } /* impSprHasEvenNumDoubleQuotes */
    
    
    /*******************************************************************************
     * impSprGetToken
     *
     */
    
    string impSprGetToken(Stream file, Buffer &bLine, char cSep, bool bPreserve_nl) {
        string  token = ""
        Buffer b = create()
        
        setempty(b)
    
        if (bLine[0] == cSep) {
            bLine = tempStringOf(bLine[1:])
            token = ""
        } else if (bLine[0] == cDoubleQuote) {
            setempty bWork
            while (!impSprHasEvenNumDoubleQuotes(bWork)) {
                if (reQuotes1(bLine)) {
                    bWork += tempStringOf(bLine[0:end 0])
                    bLine = tempStringOf(bLine[(end 0) + 1:])
                } else {
                    bWork += tempStringOf(bLine[0:(length bLine) - 1])
                    bLine = ""
                }
                if (!impSprHasEvenNumDoubleQuotes(bWork) && tempStringOf(bLine) == "") {
                    file >= b
                    bLine = tempStringOf(b)
                    nRow++
                    if (bPreserve_nl)
                        bWork += "\n"
                }
            }
            token = impSprRemoveDoubleQuotes(bWork)
        } else if (reQuotes2 bLine) {
            token = tempStringOf(bLine[0:(end 0) - 1])
            bLine = tempStringOf(bLine[(end 0) + 1:])
        } else if (reAnything(bLine) && (end 0) == (length(bLine) - 1)) {
            token = tempStringOf(bLine[0:end 0])
            bLine = ""
        }
        delete b
        return token
    
    } // impSprGetToken 
    
    
    /*******************************************************************************
     * impSprReadRow
     *
     */
    
    bool impSprReadRow(Stream stCSV, char cSep, Skip skRowData, int &i, bool bPreserve_nl) 
    {
        string token = ""
        Buffer bData = create()
    
        if (end stCSV)
            return false
    
        stCSV >= bData
        nRow++
    
        while (tempStringOf(bData) != "") {
            token = impSprGetToken(stCSV, bData, cSep, bPreserve_nl)
            put(skRowData, i++, token)
        }
    
        if (!end stCSV && null token)
        {
            put(skRowData, i++, token)
        }
    
        if (i == 0) {
            delete bData
            return false
        }
    
        if (i < nColumn) {
            while (i < nColumn)
                put(skRowData, i++, "")
        }
    
        delete bData
        return true
    
    } // impSprReadRow
    
    void importFromCSVFile(Module m, string sFile, char cSep, LogFile logFile)
    {
        pragma runLim, 0
        bWork = create()
        reportInformation(logFile << "Import from CSV file " << sFile)
        if (!fileReadable_ sFile)
        {
            reportError(logFile << "Can not read file " << sFile)
            return
        }
        updateModuleAttributes(m)
    
        stCSV = read sFile
        nRow = 0
        Buffer b = create()
        while(!end(stCSV))
        {
            stCSV >= b
            ++nRow 
        }
        close(stCSV)
        stCSV = read sFile
        
        reQuotes1 = regexp "[^\"]*\"" cSep ""
        reQuotes2 = regexp "[^" cSep "]*" cSep ""
        
        if (!null skColumnHeaders)
            delete skColumnHeaders
        skColumnHeaders = create()
        nColumn = 0
        
        if (!impSprReadRow(stCSV, cSep, skColumnHeaders, nColumn, false)) 
        {
            reportError(logFile << "No data to load in file " << sFile)
            return
        } 
        Skip skAttributes = create()
        string sColumnHeader
        for sColumnHeader in skColumnHeaders do
        {
            int nColumn = (int(key(skColumnHeaders)))
            string sAttribute
            if (find(skColumnHeader2Attribute, sColumnHeader, sAttribute))
            {
                put(skAttributes, nColumn, sAttribute)
            }
        }
        Object o = last(m)
        if (null o)
            o = create(m)
        progressStart(getUI(), "CORE Import, from CSV", "", nRow)
        bool bDone = false
        int nRow = 1
        while (!end stCSV) 
        {
            progressStep(nRow)
            progressMessage(nRow "")
            if (!null skRowData)
                delete skRowData
            skRowData = create()
            nColumn = 0
            int i = 0
            if (impSprReadRow(stCSV, cSep, skRowData, i, true)) 
            {
                string sValue
                for sValue in skRowData do
                {
                    int n = (int key(skRowData))
                    string sAttribute
                    if (find(skAttributes, n, sAttribute))
                        transferCellContent(o, sAttribute, sValue, logFile)
                }
            }
            if (progressCancelled())
            {
                reportError(logFile << "Import aborted by user after " << nRow "" << " Requirements")
                break
            }
            i = 0
            o = create(o)
            ++nRow
        }
        reportSuccess(logFile << "Imported " << nRow "" << " Requirements")
        progressStop()
        delete bWork
        delete skAttributes
        delete skColumnHeaders
        return
    }