2018-10-28 08:43 PM
2018-10-29 03:45 PM
2018-11-19 06:34 PM
2020-11-12 03:41 PM
2020-11-20 06:51 AM
2020-11-22 08:39 PM
2020-11-30 04:53 PM
2023-04-11 10:32 AM
In the past, I once created an elaborate Excel with formulas (no VBA) to generate the different text fragments I needed for the XML. But that was too much effort and hardly reusable. And I had to copy-paste the text into the XML manually.
I recently used a custom Python script to convert existing classifications in the format Archicad expects. One was starting from an Excel table (CCTB), the other from an XML file (ETIM).
Archicad expects a certain XML structure of tags, before it accepts a classification import.
It's not a generic plug-and-play for ANY Excel, but it was not too much work either. Most work was figuring out a correct hierarchy from the numbering in the source Excel. The rest is straightforward.
E.g. reading the Excel
import openpyxl
import xml.etree.ElementTree as ET
####################################################################
# Parse Excel file
####################################################################
print("Parsing Excel File")
workbook = openpyxl.load_workbook(input, data_only=True) # ignore formulas
# Dict to keep items (flat, at this point)
itemsFlat = {}
for worksheet in workbook:
for row in worksheet.iter_rows():
code = row[0].value
description = row[1].value
itemsFlat[code] = description
And then setting up a suitable XML structure is something like this:
# root
buildingInformation = ET.Element('BuildingInformation')
classification = ET.SubElement(buildingInformation, 'Classification')
# Classification System
system = ET.SubElement(classification, 'System')
name = ET.SubElement(system, 'Name')
name.text = systemName
editionVersion = ET.SubElement(system, 'EditionVersion')
editionVersion.text = version
editionDate = ET.SubElement(system, 'EditionDate')
year = ET.SubElement(editionDate, 'Year')
year.text = dateYear
month = ET.SubElement(editionDate, 'Month')
month.text = dateMonth
day = ET.SubElement(editionDate, 'Day')
day.text = dateDay
description = ET.SubElement(system, 'Description')
description.text = systemDescription
source = ET.SubElement(system, 'Source')
source.text = systemSource
# Items
items = ET.SubElement(system, 'Items')
Then there is a specific section to parse and interpret the strings from Excel into a structure that suits Archicad... I parse the "itemsFlat" dictionary and for each items calls a custom "writeItem" function which takes a parent XML item and the two strings (ID and Name) to be added to the 'Items' tag (created in the last line of the previous fragment).
And finally writing the XML:
## Write the XML (with proper encoding header string)
tree = ET.ElementTree("tree")
tree._setroot(buildingInformation)
tree.write(systemName + "_" + version + ".xml", encoding="UTF-8", xml_declaration= True)