Função para indentar um arquivo XML via AdvPL

Função para indentar um arquivo XML via AdvPL

Olá pessoal…

Hoje vou mostrar uma rotina desenvolvida em AdvPL, que serve para indentar um arquivo XML, deixando com espaços a esquerda entre as tags.

Se algum dia você já precisou indentar um XML e não utiliza o Pretty Print XML do Notepad++, foi feito uma função em AdvPL, que você passa o conteúdo, e ele te retorna indentado, por exemplo, supondo que você tenha esse XML:

<dados><nome>Daniel</nome><cidade>Bauru</cidade></dados>

Ao rodar a rotina, o texto ficaria assim:

<dados>
  <nome>
    Daniel
  </nome>
  <cidade>
    Bauru
  </cidade>
</dados>

Abaixo o código fonte desenvolvido:

//Bibliotecas
#Include "Protheus.ch"

/*/{Protheus.doc} zPrettyXML
Função que serve para quebrar um XML e deixá-lo indentado para o usuário
@author Atilio
@since 13/05/2018
@version 1.0
@param cTextoOrig, characters, descricao
@type function
@example Exemplo Abaixo
	//..............
	cTextoOrig := MemoRead("C:\TOTVS\notas\original.xml")
	cTextoNovo := ""
	
	cTextoNovo := u_zPrettyXML(cTextoOrig)
	
	Aviso('Atenção', cTextoNovo, {'OK'}, 03)
	//..............
/*/

User Function zPrettyXML(cTextoOrig)
	Local aArea      := GetArea()
	Local cTextoNovo := ""
	Local aLinhas    := {}
	Local cEspaco    := ""
	Local nAbriu     := 0
	Local nAtual     := 0
	Local aLinNov    := {}
	
	//Se tiver conteúdo texto, e tiver o trecho de XML
	If ! Empty(cTextoOrig) .And. '<?xml version=' $ cTextoOrig
		
		//Substitui a fecha chaves para um enter
		cTextoNovo := StrTran(cTextoOrig, "</",                "zPrettyXML_QUEBR")
		cTextoNovo := StrTran(cTextoNovo, "<",                 CRLF + "<")
		cTextoNovo := StrTran(cTextoNovo, ">",                 ">" + CRLF)
		cTextoNovo := StrTran(cTextoNovo, "zPrettyXML_QUEBR",  CRLF + "</")
		
		//Pega todas as linhas
		aLinhas := StrTokArr(cTextoNovo, CRLF)
		
		//Percorre as linhas adicionando espaços em branco
		For nAtual := 1 To Len(aLinhas)
			//Somente se tiver conteúdo
			If ! Empty(aLinhas[nAtual])
			
				//Se for abertura de tag, e não for fechamento na mesma linha, aumenta a tabulação 
				If "<" $ aLinhas[nAtual] .And. ! "<?" $ aLinhas[nAtual] .And. ! "</" $ aLinhas[nAtual] .And. ! "/>" $ aLinhas[nAtual]
					nAbriu += 1
				EndIf
				
				//Definindo a quantidade de espaços em branco, conforme número de tags abertas
				cEspaco := ""
				If nAbriu > 0
					cEspaco := Replicate(' ', 2 * (nAbriu + Iif(! "<" $ aLinhas[nAtual], 1, 0)) )
				EndIf
				
				//Monta agora o texto com a tabulação
				aAdd(aLinNov, cEspaco + aLinhas[nAtual])
				
				//Se for fechamento de tag, diminui a tabulação
				If "</" $ aLinhas[nAtual] .And. At('<', SubStr(aLinhas[nAtual], 2, Len(aLinhas[nAtual]))) == 0
					nAbriu -= 1
				EndIf
			EndIf
		Next
		
		//Monta agora o texto novo
		cTextoNovo := ""
		For nAtual := 1 TO Len(aLinNov)
			cTextoNovo += aLinNov[nAtual] + CRLF
		Next
	EndIf
	
	RestArea(aArea)
Return cTextoNovo

Esses e outros códigos, estão disponíveis gratuitamente no nosso GitHub, acesse em github.com/dan-atilio/AdvPL.
Caso queira uma customização específica para sua empresa, saiba mais em nossa Loja.

Bom pessoal, por hoje é só.
Abraços e até a próxima.

About Dan_Atilio

Analista e desenvolvedor de sistemas. Técnico em Informática pelo CTI da Unesp. Graduado em Banco de Dados pela Fatec Bauru. Entusiasta de soluções Open Source e blogueiro nas horas vagas. Autor do projeto Terminal de Informação, onde são postados tutoriais e notícias envolvendo o mundo da tecnologia.

Deixe uma resposta

%d blogueiros gostam disto: