Disponible en descarga gratuita Cuadernos de Viaje - Oriente Próximo, el libro con nuestras aventuras en Jordania, Siria e Israel.

miércoles, 30 de abril de 2008

PrettyXML en gawk

Hoy voy a volver al origen del blog: aquello de apuntar las cosas para que no se me olviden y saber dónde encontrarlas si las vuelvo a necesitar.

Últimamente estoy programando scripts en gawk, un lenguaje de scripts bastante potente diseñado para trabajar con ficheros de texto plano. Lo que me ha tenido entretenido los últimos días ha sido una función que dado un texto XML lo devuelva indentado, bonito (pretty) para que se pueda leer con facilidad.

Aquí pongo la función esperando que le pueda resultar útil a alguien y también que, si se encuentran errores me avisen para corregirlos. Pongo los comentarios en inglés porque tenía que ponerlos en inglés en el trabajo, además así se puede aprovechar por más gente.



# This function returns a string formed by "char" "n" times.

function nChars(n,char,
str,i){
str="";
for( i = 0; i < n; i++ ){
str = str char;
}
return( str );
}


# This function chages an xml message to a pretty XML format.
# The "<" and the ">" characters are changed by "####" and "##"
# respectively (Variable openTag and closeTag).
# I assume that these characters sequences won't appear in the
# original message
# The indentation is made using the indentChar variable.

function prettyXML(msg,
indent, charPrev, charNext, replace, indentChar, openTag,
closeTag){
indent = 0;
indentChar = " ";
openTag = "####";
closeTag = "##";
while( match(msg,/>[ \r\t\n]*</ )) {
charPrev = substr( msg, RSTART-1, 1 );
charNext = substr( msg, RSTART+RLENGTH, 1 );

# If the next char after the regular expression is "/"
# it means that the next tag is a closing tag,
# so it's necessary to subtract one from indentation;
# otherwise it's necessary check the previous char before
# to add one indentation, only when the
# previous tag is not a closing tag.

if( charNext == "/" ) {
indent --;
} else {
if( charPrev != "/" \
&& substr(msg, 1, RSTART) !~ openTag "/[^#<]*>$" \
&& substr(msg, 1, RSTART) !~ /<\/[^#<]*>$/ ) {
indent ++;
}
}
replace = closeTag "\n" nChars(indent, indentChar) openTag;
sub( />[ \r\t\n]*<;/, replace, msg )
}
gsub( openTag, "<", msg );
gsub( closeTag, ">", msg );

return ( msg );
}

Los habituales que no se me enfaden, que volveré con temas más asequibles después del puente: Feliz día del trabajador a todos, y buen puente para el que lo tenga.

3 comentarios:

Masmi dijo...

Es un lenguaje de script de UNIX?
La sintaxis es muy similar al C
Buen puente!

JAAC dijo...

Sí, pero también hay gawk para Windows (obviamente para Linux no hay ni que decirlo).
Está basado en librerías de C, y ha adoptado casi toda su sintaxis, incluyendo toda la potencia de las expresiones regulares.
Últimamente estoy ampliando mucho mi horizonte de lenguajes de programación, del sólo Java, he pasado al Java, C, C++, Tcl, gawk,...

Anónimo dijo...

off white nike
jordan 1
golden goose outlet
kevin durant shoes
a bathing ape