Criar XML com TXmlManager

Boa tarde!

É possível criar um XML do zero ao utilizar a classe TXmlManager? Ou ela apenas faz leituras e manipulação?

Se sim, quais métodos posso estar utilizando para recriar um XML similar ao abaixo?


<Cli TipCli="1" IdfcCli="1213131313" NmCli="aaaaaaaa">
    <EndCli LgrEndCli="Q B" NrEndCli="9"  CmptEndCli="aaaaaaa" BaiEndCli="bbbbbbb" CepEndCli="99999999" MunEndCli="aaaaaaaa" UfEndCli="ee"/>
    <TelCli DddTelCli="00" NrTelCli="99999999"/>
    <EndEtnCli EmaiCli="NAOPOSSUI@HOTMAIL.COM"/>
</Cli>

Giordano,

Fiz alguns testes, e não achei uma forma de criar o primeiro elemento do XML via classe TXmlManager.

Criando o primeiro elemento via o método parse, aí foi possível criar os demais elementos e atributos, inclusive de formas diferentes. Abaixo o resultado que consegui chegar durante os testes:


#include "protheus.ch"

//-------------------------------------------------------------------
/*/{Protheus.doc} u_xmlBuilder
Exemplo de criação de XML utilizando a classe TXmlManager

@author Daniel Mendes
@since Jul 08, 2022
@version 1.0
/*/
//-------------------------------------------------------------------
function u_xmlBuilder()
local oXml as object

oXml := TXmlManager():New()

//Usando os métodos de XPath...
if oXml:parse("<Cli></Cli>")
    oXml:XPathAddAtt("/Cli", "TipCli", "1")
    oXml:XPathAddAtt("/Cli", "IdfcCli", "1213131313")
    oXml:XPathAddAtt("/Cli", "NmCli", "aaaaaaaa")

    oXML:XPathAddNode("/Cli", "EndCli", "" )
    oXml:XPathAddAtt("/Cli/EndCli", "LgrEndCli", "Q B")
    oXml:XPathAddAtt("/Cli/EndCli", "NrEndCli", "9")
    oXml:XPathAddAtt("/Cli/EndCli", "CmptEndCli", "aaaaaaa")
    oXml:XPathAddAtt("/Cli/EndCli", "BaiEndCli", "bbbbbbb")
    oXml:XPathAddAtt("/Cli/EndCli", "CepEndCli", "99999999")
    oXml:XPathAddAtt("/Cli/EndCli", "MunEndCli", "aaaaaaaa")
    oXml:XPathAddAtt("/Cli/EndCli", "UfEndCli", "ee")

    oXML:XPathAddNode("/Cli", "TelCli", "" )
    oXml:XPathAddAtt("/Cli/TelCli", "DddTelCli", "00")
    oXml:XPathAddAtt("/Cli/TelCli", "NrTelCli", "99999999")

    oXML:XPathAddNode("/Cli", "EndEtnCli", "" )
    oXml:XPathAddAtt("/Cli/EndEtnCli", "EmaiCli", "NAOPOSSUI@HOTMAIL.COM")

    conOut(oXml:Save2String())
endif

freeObj(oXml)

oXml := TXmlManager():New()

//Usando os métodos de DOM... que navegam pelo XML
if oXml:parse("<Cli></Cli>")
    oXml:DOMAddAtt("TipCli", "1")
    oXml:DOMAddAtt("IdfcCli", "1213131313")
    oXml:DOMAddAtt("NmCli", "aaaaaaaa")

    oXML:DOMNewChildNode("EndCli", "" )
    oXML:DOMChildNode()

    oXml:DOMAddAtt("LgrEndCli", "Q B")
    oXml:DOMAddAtt("NrEndCli", "9")
    oXml:DOMAddAtt("CmptEndCli", "aaaaaaa")
    oXml:DOMAddAtt("BaiEndCli", "bbbbbbb")
    oXml:DOMAddAtt("CepEndCli", "99999999")
    oXml:DOMAddAtt("MunEndCli", "aaaaaaaa")
    oXml:DOMAddAtt("UfEndCli", "ee")

    oXML:DOMParentNode()
    oXML:DOMNewChildNode("TelCli", "" )
    oXML:DOMChildNode()
    oXML:DOMNextNode()
    oXml:DOMAddAtt("DddTelCli", "00")
    oXml:DOMAddAtt("NrTelCli", "99999999")

    oXML:DOMParentNode()
    oXML:DOMNewChildNode("EndEtnCli", "" )
    oXML:DOMChildNode()
    oXML:DOMNextNode()
    oXML:DOMNextNode()
    oXml:DOMAddAtt("EmaiCli", "NAOPOSSUI@HOTMAIL.COM")

    conOut(oXml:Save2String())
endif

freeObj(oXml)

return

Para solucionar o problema do primeiro elemento, você pode criar um factory de TXmlManager, que já retorne a instância do TXmlManager com o primeiro elemento, algo assim:


//-------------------------------------------------------------------
/*/{Protheus.doc} u_xmlManagerFactory
Factory de TXmlManager para construção de XML

@param cFirstNode, character, nome do primeiro elemento do XML

@return oXmlManager, object, instância da TXmlManager já com elemento criado e válido

@author Daniel Mendes
@since Jul 08, 2022
@version 1.0
/*/
//-------------------------------------------------------------------
function u_xmlManagerFactory(cFirstNode)
local oXmlManager as object

oXmlManager := TXmlManager():new()
oXmlManager:parse("<" + cFirstNode + "></" + cFirstNode + ">")

return oXmlManager

Documentação: https://tdn.totvs.com/display/tec/Classe+TXmlManager

Muito obrigado, Daniel.

Daniel, sabe me informar como posso fazer quando eu tiver mais de um elemento cli? Por exemplo: uma listagem de clientes onde cada cliente é um elemento cli. Estou tentando desenvolver mas ele sempre cria um elemento cli com atributos de vários clientes.