Guest User

awkxml

a guest
Jul 19th, 2011
6,885
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Awk 6.82 KB | None | 0 0
  1. #!/usr/bin/awk -f
  2.  
  3. BEGIN {
  4.      while ( getXML(ARGV[1],1) ) {
  5.          printf ("%s %s %s ",XTYPE, XITEM, XPATH);
  6.          for (attrName in XATTR)
  7.              printf ("%s=%s ", attrName, XATTR[attrName]);
  8.          print
  9.      }
  10.      if (XERROR) {
  11.          print XERROR;
  12.          exit 1;
  13.      }
  14.  
  15. }
  16.  
  17. ##
  18. # getXML( file, skipData ): # read next xml-data into XTYPE,XITEM,XATTR
  19. # Parameters:
  20. #   file       -- path to xml file
  21. #   skipData   -- flag: do not read "DAT" (data between tags) sections
  22. # External variables:
  23. #   XTYPE      -- type of item read, e.g. "TAG"(tag), "END"(end tag), "COM"(comment), "DAT"(data)
  24. #   XITEM      -- value of item, e.g. tagname if type is "TAG" or "END"
  25. #   XATTR      -- Map of attributes, only set if XTYPE=="TAG"
  26. #   XPATH      -- Path to current tag, e.g. /TopLevelTag/SubTag1/SubTag2
  27. #   XLINE      -- current line number in input file
  28. #   XNODE      -- XTYPE, XITEM, XATTR combined into a single string
  29. #   XERROR     -- error text, set on parse error
  30. # Returns:
  31. #    1         on successful read: XTYPE, XITEM, XATTR are set accordingly
  32. #    ""        at end of file or parse error, XERROR is set on error
  33. # Private Data:
  34. #   _XMLIO     -- buffer, XLINE, XPATH for open files
  35. ##
  36. function getXML( file, skipData           ,end,p,q,tag,att,accu,mline,mode,S0,ex,dtd) {
  37.      XTYPE=XITEM=XERROR=XNODE=""; split("",XATTR);
  38.      S0=_XMLIO[file,"S0"]; XLINE=_XMLIO[file,"line"]; XPATH=_XMLIO[file,"path"]; dtd=_XMLIO[file,"dtd"];
  39.      while (!XTYPE) {
  40.          if (S0=="") { if (1!=(getline S0 <file)) break; XLINE++; S0=S0 RS; }
  41.          if ( mode == "" ) {
  42.              mline=XLINE; accu=""; p=substr(S0,1,1);
  43.              if ( p!="<" && !(dtd && p=="]") )         mode="DAT";
  44.              else if ( p=="]" ) {                      S0=substr(S0,2);  mode="DTE"; end=">"; dtd=0; }
  45.              else if ( substr(S0,1,4)=="<!--" ) {      S0=substr(S0,5);  mode="COM"; end="-->"; }
  46.              else if ( substr(S0,1,9)=="<!DOCTYPE" ) { S0=substr(S0,10); mode="DTB"; end=">"; }
  47.              else if ( substr(S0,1,9)=="<![CDATA[" ) { S0=substr(S0,10); mode="CDA"; end="]]>"; }
  48.              else if ( substr(S0,1,2)=="<!" ) {        S0=substr(S0,3);  mode="DEC"; end=">"; }
  49.              else if ( substr(S0,1,2)=="<?" ) {        S0=substr(S0,3);  mode="PIN"; end="?>"; }
  50.              else if ( substr(S0,1,2)=="</" ) {        S0=substr(S0,3);  mode="END"; end=">";
  51.                  tag=S0;sub(/[ \n\r\t>].*$/,"",tag);S0=substr(S0,length(tag)+1);
  52.                  ex=XPATH;sub(/\/[^\/]*$/,"",XPATH);ex=substr(ex,length(XPATH)+2);
  53.                  if (tag!=ex) { XERROR="unexpected close tag <" ex ">..</" tag ">"; break; } }
  54.              else{                                     S0=substr(S0,2);  mode="TAG";
  55.                  tag=S0;sub(/[ \n\r\t\/>].*$/,"",tag);S0=substr(S0,length(tag)+1);
  56.                  if ( tag !~ /^[A-Za-z:_][0-9A-Za-z:_.-]*$/ ) { # /^[[:alpha:]:_][[:alnum:]:_.-]*$/
  57.                      XERROR="invalid tag name '" tag "'"; break; }
  58.                  XPATH = XPATH "/" tag; } }
  59.          else if ( mode == "DAT" ) {                            # terminated by "<" or EOF
  60.              p=index(S0,"<"); if ( dtd && (q=index(S0,"]")) && (!p || q<p) ) p=q;
  61.              if (p) {
  62.                  if (!skipData) { XTYPE="DAT"; XITEM=accu unescapeXML(substr(S0,1,p-1)); }
  63.                  S0=substr(S0,p); mode=""; }
  64.              else{ if (!skipData) accu=accu unescapeXML(S0); S0=""; } }
  65.          else if ( mode == "TAG" ) {   sub(/^[ \n\r\t]*/,"",S0); if (S0=="") continue;
  66.              if ( substr(S0,1,2)=="/>" ) {
  67.                  S0=substr(S0,3); mode=""; XTYPE="TAG"; XITEM=tag; S0="</"tag">"S0; }
  68.              else if ( substr(S0,1,1)==">" ) {
  69.                  S0=substr(S0,2); mode=""; XTYPE="TAG"; XITEM=tag; }
  70.              else{
  71.                  att=S0; sub(/[= \n\r\t\/>].*$/,"",att); S0=substr(S0,length(att)+1); mode="ATTR";
  72.                  if ( att !~ /^[A-Za-z:_][0-9A-Za-z:_.-]*$/ ) { # /^[[:alpha:]:_][[:alnum:]:_.-]*$/
  73.                      XERROR="invalid attribute name '" att "'"; break; } } }
  74.          else if ( mode == "ATTR" ) {  sub(/^[ \n\r\t]*/,"",S0); if (S0=="") continue;
  75.              if ( substr(S0,1,1)=="=" ) { S0=substr(S0,2); mode="EQ"; }
  76.              else                       { XATTR[att]=att; mode="TAG"; XNODE=XNODE att"="att"\001"; } }
  77.          else if ( mode == "EQ" ) {    sub(/^[ \n\r\t]*/,"",S0); if (S0=="") continue;
  78.              end=substr(S0,1,1);
  79.              if ( end=="\"" || end=="'" ) {S0=substr(S0,2);accu="";mode="VALUE";}
  80.              else{
  81.                  accu=S0; sub(/[ \n\r\t\/>].*$/,"",accu); S0=substr(S0,length(accu)+1);
  82.                  XATTR[att]=unescapeXML(accu); mode="TAG"; XNODE=XNODE att"="XATTR[att]"\001"; } }
  83.          else if ( mode == "VALUE" ) {                          # terminated by end
  84.              if ( p=index(S0,end) ) {
  85.                  XATTR[att]=accu unescapeXML(substr(S0,1,p-1)); XNODE=XNODE att"="XATTR[att]"\001";
  86.                  S0=substr(S0,p+length(end)); mode="TAG"; }
  87.              else{ accu=accu unescapeXML(S0); S0=""; } }
  88.          else if ( mode == "DTB" ) {                            # terminated by "[" or ">"
  89.              if ( (q=index(S0,"[")) && (!(p=index(S0,end)) || q<p ) ) {
  90.                  XTYPE=mode; XITEM= accu substr(S0,1,q-1); S0=substr(S0,q+1); mode=""; dtd=1; }
  91.              else if ( p=index(S0,end) ) {
  92.                  XTYPE=mode; XITEM= accu substr(S0,1,p-1); S0="]"substr(S0,p); mode=""; dtd=1; }
  93.              else{ accu=accu S0; S0=""; } }
  94.          else if ( p=index(S0,end) ) {  # terminated by end
  95.              XTYPE=mode; XITEM= ( mode=="END" ? tag : accu substr(S0,1,p-1) );
  96.              S0=substr(S0,p+length(end)); mode=""; }
  97.          else{ accu=accu S0; S0=""; } }
  98.      _XMLIO[file,"S0"]=S0; _XMLIO[file,"line"]=XLINE; _XMLIO[file,"path"]=XPATH; _XMLIO[file,"dtd"]=dtd;
  99.      if (mode=="DAT") { mode=""; if (accu!="") XTYPE="DAT"; XITEM=accu; }
  100.      if (XTYPE) { XNODE=XTYPE"\001"XITEM"\001"XNODE; return 1; }
  101.      close(file);
  102.      delete _XMLIO[file,"S0"]; delete _XMLIO[file,"line"]; delete _XMLIO[file,"path"]; delete _XMLIO[file,"dtd"];
  103.      if (XERROR) XERROR=file ":" XLINE ": " XERROR;
  104.      else if (mode) XERROR=file ":" mline ": " "unterminated " mode;
  105.      else if (XPATH) XERROR=file ":" XLINE ": "  "unclosed tag(s) " XPATH;
  106.  
  107. } # function getXML
  108.  
  109. # unescape data and attribute values, used by getXML
  110. function unescapeXML( text ) {
  111.      gsub( "&apos;", "'",  text );
  112.      gsub( "&quot;", "\"", text );
  113.      gsub( "&gt;",   ">",  text );
  114.      gsub( "&lt;",   "<",  text );
  115.      gsub( "&amp;",  "\\&",  text );
  116.      return text
  117.  
  118. }
  119.  
  120. # close xml file
  121. function closeXML( file ) {
  122.      close(file);
  123.      delete _XMLIO[file,"S0"]; delete _XMLIO[file,"line"]; delete _XMLIO[file,"path"]; delete _XMLIO[file,"dtd"];
  124.      delete _XMLIO[file,"open"]; delete _XMLIO[file,"IND"];
  125. }
Advertisement
Add Comment
Please, Sign In to add comment