maps and xml issue

Started by spl, March 12, 2025, 01:38:59 PM

Previous topic - Next topic

spl

While most URL api's return json, xml is still prevalent. WB's CLR makes it easy to create and process xml data via ObjectClrOption("useany","System.Xml"). Below is code to create an xml configuration. It attempts to create the elements from 2 maps one which is meant to call the other. Please read through this before judgments.

First code: Will build basic elements from config map, but note code has 2 commented lines related to the 'sub' map meant to file in the values for the Database element subelemenmts.
;Winbatch 2025A - Create xml configuration
;=========================================
gosub udfs
IntControl(73,1,0,0,0)
;create map and submap
cf = $"AppName=Winbatch Automation
Version=1.0
Database=SubDatabase$"
cf = StrReplace(cf, @cr, "") 
Config = MapCreate(cf, "=", @lf)

db = $"Server=localhost
Name=wbAuto.db
User=admin 
Password=password123$"
db = StrReplace(db, @cr, "") 
SubDatabase = MapCreate(db, "=", @lf)

;define xml output file and create CLR object
file = 'C:\temp\config.xml'
if fileexist(file) then filedelete(file)
ObjectClrOption("useany","System.Xml")
;insert xml elements
xmlDoc = ObjectClrNew( 'System.Xml.XmlDocument' )
xmlDoc.AppendChild(xmlDoc.CreateXmlDeclaration("1.0", "UTF-8",""))
rootElement = xmlDoc.CreateElement("Configuration")
xmlDoc.AppendChild(rootElement)
foreach key in Config
    element = xmlDoc.CreateElement(key)
    if strsub(Config[key],1,3) == "Sub"
       subkey = Config[key]
       foreach s in %subkey%
          subelement = xmlDoc.CreateElement(s)
          ;just display values in submap
          Message("subkey:":s,"Value=":%subkey%[s])

          ;uncomment line below for error
          ;subelement.Innertext = %subkey%[s] 

          ;uncomment line below to produce redundant data
          ;subelement.SetAttribute(s,%subkey%[s])

          element.AppendChild(subelement)
       next
    else
       element.InnerText = Config[key]
    endif
    rootElement.AppendChild(element)
next
xmlDoc.Save(file)
xmlDoc = 0
;check if file created
if fileexist(file)
   Message("xml created",fileget(file)) 
else
   Display(2,'xml not created',file)
endif
exit

:WBERRORHANDLER
xmlDoc=0
geterror()
Terminate(@TRUE,"Error Encountered",errmsg)

:udfs
#DefineSubRoutine geterror()
   wberroradditionalinfo = wberrorarray[6]
   lasterr = wberrorarray[0]
   handlerline = wberrorarray[1]
   textstring = wberrorarray[5]
   linenumber = wberrorarray[8]
   errmsg = "Error: ":lasterr:@LF:textstring:@LF:"Line (":linenumber:")":@LF:wberroradditionalinfo
   Return(errmsg)
#EndSubRoutine

Return


should produce an xml file with elements. Now uncomment the line ;subelement.SetAttribute(s,%subkey%), rerun script and results should be
<xml version="1.0" encoding="UTF-8"?>
<Configuration>
  <Version>1.0</Version>
  <AppName>Winbatch Automation</AppName>
  <Database>
    <Server Server="localhost" />
    <Password Password="password123" />
    <Name Name="wbAuto.db" />
    <User User="admin" />
  </Database>
</Configuration>

but what I want is
<xml version="1.0" encoding="UTF-8"?>
<Configuration>
  <Database>
    <Server>localhost</Server>
    <Password>password123</Password>
    <Name>wbAuto.db</Name>
    <User>admin</User>
  </Database>
  <AppName>Winbatch Automation</AppName>
  <Version>1.0</Version>
</Configuration>

which I thought I would get by uncommenting ;subelement.Innertext = %subkey%, assuming subelement.InnerText would operate same as element.Innertext but instead get attached error.

First, I'm not concerned with "why not do it this way" as I know there are other means to produce what I want. The code takes chances with substitution but there is a message line that displays each submap element with it's value. I also know a map element can have an array as a value. That might be a viable alternative but presently cannot wrap my head around setting it up, as a map in a map made more sense.

Appreciate anyone testing the script and suggestions welcome.
Stan - formerly stanl [ex-Pundit]

td

I guess "Innertext" is not a member of the element class.  Try "InnerText" instead.
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

spl

Quote from: td on March 12, 2025, 02:59:05 PMI guess "Innertext" is not a member of the element class.  Try "InnerText" instead.

The only tihng worse than a post is a post with a typo.
It's just reposterous.

Thanks for looking...
Stan - formerly stanl [ex-Pundit]

td

Even your typo posts illustrate useful ways to accomplish tasks.
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

spl

definition of old-school: re-writing Hungarian Notation in CamelBack and making typos.
Stan - formerly stanl [ex-Pundit]