具有各种标记名称的Csv到xml

时间:2015-04-05 10:33:53

标签: xml csv

我有这个csv文件

name;num_tel;num_fixe;id_client;num_comd;email;city;date_liv
gwenael;0998452223;1038431234;50C;12345;gwa@yahoo.fr;London;08/07/2015
marcel;0966442312;1038453211;31C;654321;marcel@yahoo.fr;Pairs;08/06/2015
judith;0954674487;1045227937;23D;78965;judith@yahoo.fr;Toulouse;11/05/2015
paul;0998452223;1038431234;35X;19945;paul@yahoo.fr;Bordeaux;01/04/2015
toto;0966442312;1038453211;31Z;994991;toto@yahoo.frNice;02/12/2015 
marie;0954674487;1045227937;23C;78944;marie@yahoo.fr;Lille;04/08/2015
jacque;0998452223;1038431234;77C;18845;jacque@yahoo.fr;Bruges;09/05/2015
trucmuche;0966442312;1038453211;31Z;666321;trucmuche@yahoo.fr;Berlin;10/04/2015 
tata;0954674487;1045227937;23D;77965;tata@yahoo.fr;New-york;08/07/2015

在我的情况下,那些标签名称是默认值,用户有可能拥有  更多标签名称例如我添加了城市,date_liv。所以他们添加它并生成csv。  它们出现在最后一个默认标签名称(电子邮件)之后。  我想知道是否可以创建一个循环来检查csv并将它们添加到xml?  我认为循环看起来像(i = 7; i< = NF; i ++){}?但是怎么做呢?  这就是我所做的,你可以帮助我很好地形成它,我有很多错误

BEGIN {

FS=";"
documentEnclosingTag = "rows"
c_flds["id_client"];c_flds["name"];c_flds["num_cmd"];c_flds["num_tel"];d_flds["email"]
d_flds["id_client"];d_flds["name"];d_flds["num_fixe"];d_flds["num_tel"];

print "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
printf "<%s>\n", documentEnclosingTag
}

FNR==1 { gsub(" ", ""); for(i=1; i<=NF; i++) cols[$i]=i; next }

var = $(cols["ID_client_proxy"]) 
if ( var ~ /C/ )
{ print createObject( "C", c_flds ) }
else { print createObject( "D", d_flds ) }

END { printf "</%s>\n", documentEnclosingTag }

#----------- functions -----------

function createObject( enclosingTag, flds,key, s) {
    for(key in flds) {
        s = s "\t" wrapData( key, $(cols[key]) ) "\n"
    }
    return( wrapData( enclosingTag, "\n" s ) )
}

function wrapData( enclosingTag, data ) {
    return( sprintf( "<%s>%s</%s>", enclosingTag, data, enclosingTag ) )
}

1 个答案:

答案 0 :(得分:1)

这是对脚本的重写,允许将非默认的fld附加到每个“对象”类型(“C”和“D”)的已知字段。最值得注意的差异在BEGIN块中,以及解析“header”行时会发生什么:

#!/usr/bin/awk -f

BEGIN {

    FS=";"
    documentEnclosingTag = "rows"

      # name the default flds with "_", "C" and "D" represent "Objects"
    dflt_flds["id_client"] = "_CD"
    dflt_flds["name"]      = "_CD"
    dflt_flds["num_comd"]  = "_C"
    dflt_flds["num_tel"]   = "_CD"
    dflt_flds["email"]     = "_C"
    dflt_flds["num_fixe"]  = "D"

    print "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
    printf "<%s>\n", documentEnclosingTag
}

FNR==1 {
    gsub(" ", "")
    for(i=1; i<=NF; i++) {
        cols[$i]=i
        dflt = dflt_flds[$i]
        if( dflt ~ /C/ || dflt == "" ) c_flds[$i]
        if( dflt ~ /D/ || dflt == "" ) d_flds[$i]
    }
    next
}

  # set var for every record read
{ var = $(cols["id_client"]) }

  # use var to determine which kind of record to print
var ~ /C/ { print createObject( "C", c_flds ) }
var ~ /D/ { print createObject( "D", d_flds ) }

END { printf "</%s>\n", documentEnclosingTag }

#----------- functions -----------

function createObject( enclosingTag, flds,             key, s) {
    for(key in flds) {
        s = s "\t" wrapData( key, $(cols[key]) ) "\n"
    }
    return( wrapData( enclosingTag, "\n" s ) )
}

function wrapData( enclosingTag, data ) {
    return( sprintf( "<%s>%s</%s>", enclosingTag, data, enclosingTag ) )
}
  • BEGIN - 我们需要一种默认的“位掩码”和每种“对象”类型,而不是命名每个默认列。因此,使用dflt_flds数组创建该数组,该数组命名每个已知列所关联的每种可能数据类型。 _被保留为表示默认或其他已知字段。如果_是有效的“id_client”标识符,则您需要将其更改为另一个单个字符。其他字段的默认值由同一字符串中的“C”或“D”值表示。请注意,稍后将构建c_fldsd_flds - 解析标头时。
  • FNR==1 - 解析标头字段以创建cols时,请检查dflt_flds[$i]处的值。接下来,创建每个“对象”的默认fld。如果dlft匹配“C”或空字符串,则将其视为c_flds必填字段并添加到该数组中。 d_flds的构造类似。
  • 之后,咨询id_client字段以确定如何打印每个“C”和“D”类型“对象”,类似于它最初的完成方式(1),尽管“var”变量是保留并添加了一些注释。

(1)这个答案是针对不同问题的a previous answer的修改。