Thanks Christian,
Regarding your points:
-
Indeed looping def is unnecessary, although something will need to iterate through each index and populate the get_new_element list.
-
I am attaching a fixed list of inputs file, you were right, the spaghetti was incorrectly plugged. I also removed the .dyf custom node to simplify it.
XPathV5test.dyn (36.3 KB)
-
I don’t have to plug it to the custom Xpath node - that was just to check if the output came through at the end of the code. My sole purpose is to export data to the XML file.
I still don’t know how to put this all together, but I added some #comments to the script to show you my thought process. I’m mostly confused with plugging the indexed list values to the def get_new_element part, which appends the “row” object.
To put it in words, I imagine the zip function creates a dictionary index, which maps all 6 lists, and then some loop will use the def get_new_element to input 6 indexed (i+1 loop) attribute values into each new_element.
Then each “def get_new_element” will be appended to the “new_elements_list”.
And then, the list will be appended to the XPATH subgroup in the XML.
Is that the right way to look at this? Here is how I think this could work, but in Dynamo, not Python. Python could hopefully remove the “getitemAtIndex” and replace it with conditional loops.
import clr
import sys
clr.AddReference(‘ProtoGeometry’)
from Autodesk.DesignScript.Geometry import *
sys.path.append(“C:\Program Files (x86)\IronPython 2.7\Lib”)
from string import *
import xml.etree.ElementTree as ET
import itertools as IT
#List of input lists:
object_name_list = IN[0]
units_list = IN[1]
basefrequency_list = IN[2]
baseunitprice_list = IN[3]
basevid_list = IN[4]
quantity_list = IN[5]
#List of input directories and XPATH
existingfile = IN[6]
xpath = IN[7]
updatedfile = IN[8]
# The input lists are mapped to the same index value using zip.
new_objects_list = []
for object_name, units, basefrequency, baseunitprice, basevid, quantity in IT.izip_longest(object_name_list, units_list, basefrequency_list, baseunitprice_list, basevid_list, quantity_list):
new_objects_list.append([index(object_name), index(units), index(basefrequency), index(baseunitprice), index(basevid), index(quantity)])
OUT = new_objects_list
i = index()
for i in new_element_list:
i =+1
# define get_new_element() - Mapping of each index of lists to ET.
#I'm not sure about the [i], but how to pass each index, execute the def get_new_element and proceed to next index?
def get_new_element():
row = ET.Element('row')
row.attrib['name'] = room_name[i]
row.attrib['include'] = 'true'
row.attrib['units'] = units[i]
#create sub-element and set attributes
basevalues = ET.SubElement(row, 'basevalues')
#create sub-sub-element and set attributes
values = ET.SubElement(basevalues, 'values')
values.attrib['frequency'] = basefrequency[i]
values.attrib['unitprice'] = baseunitprice[i]
values.attrib['vid'] = basevid[i]
#create sub-element and set attributes
inputvalues = ET.SubElement(row, 'inputvalues')
#create sub-sub-element and set attributes
values = ET.SubElement(inputvalues, 'values')
values.attrib['amount'] = quantity[i]
values.attrib['vid'] = basevid[i]
#return mapped object = row
return row
# For each index of outlist, populate get_new_element
#read existing file
uniStr = unicode(open(existingfile, 'r').read())
#fixed = uniStr.encode('utf-8', 'replace')
fixed = uniStr.encode('ascii', 'replace')
fixed.decode('utf-8', 'replace')
treee = ET.ElementTree(ET.fromstring(fixed))
try:
root = treee.getroot()
except:
root = treee
subgroup_element = root.find(xpath)
# figure a way to append the Xpath with each new element.
new_element = get_new_element()
subgroup_element.append(new_element)
new_xml_tree_string = ET.tostring(treee.getroot())
with open(updatedfile, "wb") as f:
f.write(new_xml_tree_string)
OUT = treee
Kind regards,
Adam