Posts: 5
Threads: 1
Joined: Jun 2019
Hi all,
I have a dictionary that is grouped by terms. The terms then has a list of users associated with it. The following is the dictionary:
defaultdict(<class 'list'>, {'06242019': [5717424, 5708813, 5709635, 5711802, 5712915, 5724011, 5710878, 5731039, 5714326, 5724787, 5720029], '06102019': [5664036]})
I am using ElementTree to create an XMl file based on this grouping.
def prettify(elem):
rough_string = ElementTree.tostring(elem, encoding='UTF-8')
reparsed = minidom.parseString(rough_string)
return reparsed.toprettyxml(indent=" ")
top = Element('enterprise')
comment = Comment('XML to generate Sandbox Enrollments')
top.append(comment)
propertiesParent = SubElement(top, 'properties', {'lang':"EN"})
propertiesChildren = SubElement(propertiesParent, 'datasource')
propertiesChildren.text = "Campus Nexus"
propertiesChildren = SubElement(propertiesParent, 'target')
propertiesChildren.text = "UMA Blackboard"
propertiesChildren = SubElement(propertiesParent, 'type')
propertiesChildren.text = "XML"
groupParent1 = SubElement(top, 'membership')
comment = Comment('Enroll users in the Orientation section')
groupParent1.append(comment)
groupChild1 = SubElement(groupParent1, 'sourcedid')
groupChild1a = SubElement(groupChild1, 'source')
groupChild1a.text = "Campus Nexus"
groupChild1b = SubElement(groupChild1, 'id')
groupChild1b.text = enrollDict[0]
groupChild2 = SubElement(groupParent1, 'member')
groupChild2a = SubElement(groupChild2, 'sourcedid')
groupChild2b = SubElement(groupChild2a, 'source')
groupChild2b.text = "Campus Nexus"
groupChild2b = SubElement(groupChild2a, 'id')
groupChild2b.text = "SyStudent_" + str(enrollDict[key]) This creates a subelement for every child element though instead of grouping them by the term. Can any please shed light on how I can get this to work? Thanks!
Posts: 3,458
Threads: 101
Joined: Sep 2016
In what way is your current output different from your desired output?
It isn't clear how the dict key/values are supposed to map to xml elements.
Posts: 5
Threads: 1
Joined: Jun 2019
Hi nilamo,
Thanks for your reply. I have resolved my issue. Before, the output was creating the enrollment file I needed as such:
<?xml version="1.0" ?>
<enterprise>
<!--XML to generate Sandbox Enrollments-->
<properties lang="EN">
<datasource>Campus Nexus</datasource>
<target>UMA Blackboard</target>
<type>XML</type>
</properties>
<membership>
<!--Enroll users in the Orientation section-->
<sourcedid>
<source>Campus Nexus</source>
<id> 06242019_001</id>
</sourcedid>
<member>
<sourcedid>
<source>Campus Nexus</source>
<id>SyStudent_5717424</id>
</sourcedid>
</member>
</membership>
<membership>
<!--Enroll users in the Orientation section-->
<sourcedid>
<source>Campus Nexus</source>
<id> 06242019_001</id>
</sourcedid>
<member>
<sourcedid>
<source>Campus Nexus</source>
<id>SyStudent_5708813</id>
</sourcedid>
</member>
</membership>
<membership>
<!--Enroll users in the Orientation section-->
<sourcedid>
<source>Campus Nexus</source>
<id> 06242019_001</id>
</sourcedid>
<member>
<sourcedid>
<source>Campus Nexus</source>
<id>SyStudent_5709635</id>
</sourcedid>
</member>
</membership>
</enterprise>
Notice that a membership tag is created for each term for each student. The format I need is this:
<?xml version="1.0" ?>
<enterprise>
<!--XML to generate Sandbox Enrollments-->
<properties lang="EN">
<datasource>Campus Nexus</datasource>
<target>UMA Blackboard</target>
<type>XML</type>
</properties>
<membership>
<!--Enroll users in the Orientation section-->
<sourcedid>
<source>Campus Nexus</source>
<id> 06102019_001</id>
</sourcedid>
<member>
<sourcedid>
<source>Campus Nexus</source>
<id>SyStudent_5664036</id>
</sourcedid>
<idtype>1</idtype>
<role roletype="1">
<status>1</status>
<extension>
<x_bb_available>Y</x_bb_available>
<x_bb_row_status>0</x_bb_row_status>
<x_bb_datasource_key>MEMBERS.TXT</x_bb_datasource_key>
</extension>
</role>
</member>
</membership>
<membership>
<!--Enroll users in the Orientation section-->
<sourcedid>
<source>Campus Nexus</source>
<id> 06242019_001</id>
</sourcedid>
<member>
<sourcedid>
<source>Campus Nexus</source>
<id>SyStudent_5717424</id>
</sourcedid>
<idtype>1</idtype>
<role roletype="1">
<status>1</status>
<extension>
<x_bb_available>Y</x_bb_available>
<x_bb_row_status>0</x_bb_row_status>
<x_bb_datasource_key>MEMBERS.TXT</x_bb_datasource_key>
</extension>
</role>
</member>
<member>
<sourcedid>
<source>Campus Nexus</source>
<id>SyStudent_5708813</id>
</sourcedid>
<idtype>1</idtype>
<role roletype="1">
<status>1</status>
<extension>
<x_bb_available>Y</x_bb_available>
<x_bb_row_status>0</x_bb_row_status>
<x_bb_datasource_key>MEMBERS.TXT</x_bb_datasource_key>
</extension>
</role>
</member>
</membership>
</enterprise>
So multiple students enrolled under one single term. I was able to accomplish this byt the following code:
from collections import defaultdict
from xml.dom import minidom
from xml.etree import ElementTree
from xml.etree.ElementTree import Element, SubElement, Comment
#RETURN A PRETTY-PRINTED XML STRING FOR THE FEEDFILE.
def prettify(elem):
rough_string = ElementTree.tostring(elem, encoding='UTF-8')
reparsed = minidom.parseString(rough_string)
return reparsed.toprettyxml(indent=" ")
enrollmentDict = defaultdict(list)
for xsDate, syId in newEnrollments:
enrollmentDict[xsDate].append(syId)
#print("dict", enrollmentDict, '\n')
#CREATE XML FEED FILE HEADER
top = Element('enterprise')
comment = Comment('XML to generate Sandbox Enrollments')
top.append(comment)
propertiesParent = SubElement(top, 'properties', {'lang':"EN"})
propertiesChildren = SubElement(propertiesParent, 'datasource')
propertiesChildren.text = "Campus Nexus"
propertiesChildren = SubElement(propertiesParent, 'target')
propertiesChildren.text = "UMA Blackboard"
propertiesChildren = SubElement(propertiesParent, 'type')
propertiesChildren.text = "XML"
for key in enrollmentDict:
groupParent1 = SubElement(top, 'membership')
comment = Comment('Enroll users in the Orientation section')
groupParent1.append(comment)
groupChild1 = SubElement(groupParent1, 'sourcedid')
groupChild1a = SubElement(groupChild1, 'source')
groupChild1a.text = "Campus Nexus"
groupChild1b = SubElement(groupChild1, 'id')
groupChild1b.text = key + "_001"
for value in range(len(enrollmentDict[key])):
groupChild2 = SubElement(groupParent1, 'member')
groupChild2a = SubElement(groupChild2, 'sourcedid')
groupChild2b = SubElement(groupChild2a, 'source')
groupChild2b.text = "Campus Nexus"
groupChild2b = SubElement(groupChild2a, 'id')
groupChild2b.text = "SyStudent_" + str(enrollmentDict[key][value])
groupChild3 = SubElement(groupChild2, 'idtype')
groupChild3.text = '1'
groupChild4 = SubElement(groupChild2, 'role', roletype = '1')
groupChild5 = SubElement(groupChild4, 'status')
groupChild5.text = '1'
groupChild6 = SubElement(groupChild4, 'extension')
groupChild6a = SubElement(groupChild6, 'x_bb_available')
groupChild6a.text = 'Y'
groupChild6b = SubElement(groupChild6, 'x_bb_row_status')
groupChild6b.text = '0'
groupChild6c = SubElement(groupChild6, 'x_bb_datasource_key')
groupChild6c.text = 'MEMBERS.TXT'
print(prettify(top)) I hope this can help others struggling with this same issue.
Posts: 5
Threads: 1
Joined: Jun 2019
Jul-27-2019, 09:25 PM
(This post was last modified: Jul-27-2019, 09:25 PM by pygrrrl.)
In an effort to make my code more "pythonic" and to include new requirements, I modified it to use functions for the various parts of the program. This put me back at square one with my problem. So here is the new issue:
I need to create and XML file for enrollments into various sections. The max number of sections per term is 40. The max number of students per section is 20. I also take into account the number of users already enrolled into a particular section, so if there are already 10 enrolled my XML should only generate for 10 more students. If there are more than 10 remaining students to enroll, a new section needs to be created and the process repeats. The original dictionary of new students contains the following data:
new students defaultdict(<class 'list'>, {'07292019': [5764146, 5764208, 5628056, 5764962, 5765238, 5765098, 5505275, 5764173, 5758004, 5710184, 4281360, 5724284, 5733611, 5664975, 5763188, 5763632, 5761705, 5764626, 5755932, 2749228, 5763146, 5763767, 141868, 5764928, 5764098, 5765211, 5197807, 5758318, 5591460, 5765007, 4331521, 2316969, 5762638, 5020512, 5742032, 5735627, 5012332, 5757641, 5765152, 5619975, 5762265, 5751185, 5764934, 5760885, 5764641, 5759250, 5756844, 5640685, 5741031, 4548617, 5516464, 5760699, 1755282, 3124116, 5756089, 5764854, 5762379, 5764795, 5734983, 5743824, 5647198, 4189658, 2864329, 5764805, 5764484, 5736883, 3222262, 3913367, 5765180, 5760120, 5763736, 5764400, 5764920, 5174953, 5755354, 1818845, 5765071, 5765024, 5737104, 3911357, 5764094, 5760259, 5744785, 5764790, 5196707, 5763599, 5763919, 5309074, 5758499, 4153299, 5763834, 5758908, 5764293, 5748717, 5747788, 5760961, 5764277, 5764750, 5747557, 3255138, 5764997, 5518793, 5762890, 5763094, 5765173, 5764496, 5733927, 2856506, 5763932, 5762777, 5038537, 626824, 5761819, 3150933, 5764796, 5763820, 5764038, 5763600, 5611245, 2350080, 5760793, 5494648, 5761753, 1554277, 5607548, 5765026, 3636089, 260446, 5764183, 5761714, 5581201, 5763694, 4648783, 5763733, 5764083, 5765029, 5764337, 5754852, 5765107, 5759288, 5765137, 5736457, 5023053, 5755798, 2934085, 5745608, 5755050, 5764494, 5764902, 5763917, 5764407, 5748954, 5760964, 5753269, 5751431, 4610224, 5765111, 5764835, 1068460, 5750322, 1626712, 5764296, 4875391, 5484910, 807811, 5764687, 5765011, 5763639, 3206502, 5764214, 5764592, 371518, 5763223, 5765144, 5765280, 5764925, 5762446, 5764301, 5761136, 5763961, 4252721, 5628297, 5110022, 5765175, 5764591, 4766019, 5734281, 5760056, 3212906, 5765089, 5759291, 5764989, 5761555, 5739075, 5758566, 5763804, 5763687, 5760210, 5763893, 4058257, 5764018, 2602095, 3091127, 5765093, 5762571, 5762951, 509021, 5665917, 3440598, 4767701, 5764003, 5639083, 5761191, 5758913, 5763925, 5751723, 1971322, 5652868, 5765114, 4890931, 5298765, 3627468, 5764335, 5742484, 4107920, 5755649, 5764524, 4774336, 5764500, 3393552, 5753368, 5764116, 5746728, 5764136, 1287969, 5764156, 5765212, 5760509, 5744859, 1018083, 4509889, 5764218, 5763659, 5368815, 1098686, 4559495, 3829964, 4584229, 4432291, 4333698, 3695445, 5759103, 5759038, 5759180, 5758893, 3871343, 4368225, 3922298, 4049434, 4521245, 4426735, 4455728, 4291088, 4693206, 4584675], '08192019': [5759515, 5759552, 5759554, 5759039, 5759043, 5759044, 5759577, 5759036, 5759242]})
The counts of already existing students in existing terms/sections are:
count {'07152019_001': 200, '07152019_002': 201, '07292019_001': 9, '07152019_003': 171, '04152019_001': 1}
Since there are already 9 students enrolled into section 1 for term 07292019_001, I need to enroll the first 11 new students into the section, then enroll the next 20 into section 2 and so on.
My code is as follows:
import pyodbc
from datetime import datetime as dt
from collections import defaultdict
from xml.dom import minidom
from xml.etree import ElementTree
from xml.etree.ElementTree import Element, SubElement, Comment
#GET LIST OF NEW ENROLLMENTS TO PROCESS
def get_new_enrollments(cursor):
SQL1 = "SELECT ExpectedStartDate, SyStudentID FROM [LMS_Data].[OrientationStudentInformation] WHERE OrientationSection IS NULL order by ExpectedStartDate asc"
cursor.execute(SQL1)
newEnrolls = cursor.fetchall()
newEnrollments = []
if not newEnrolls:
print("There are no new enrollments to process for Sandbox.")
else:
for row in newEnrolls:
expStartDate = dt.strftime(row[0], '%m%d%Y')
row[0] = expStartDate
newEnrollments.append(row)
enrollmentDict = defaultdict(list)
for xsDate, syId in newEnrollments:
enrollmentDict[xsDate].append(syId)
return(enrollmentDict)
#RETURN A PRETTY-PRINTED XML STRING FOR THE FEEDFILE
def prettify(elem):
rough_string = ElementTree.tostring(elem, encoding='UTF-8')
reparsed = minidom.parseString(rough_string)
return(reparsed.toprettyxml(indent=" "))
#GET CURRENT COUNT OF ENROLLMENTS BY SECTION FROM DB TABLE
def current_enrollment_count(cursor):
SQL2 = ("SELECT OrientationSection, SyStudentID from [LMS_Data].[OrientationStudentInformation] where OrientationSection IS NOT NULL")
cursor.execute(SQL2)
currEnroll = cursor.fetchall()
sectionDict = {}
for section, student in currEnroll:
sectionDict.setdefault(section, []).append(student)
numStudents = {}
for sec, stu in sectionDict.items():
numStudents.update({sec: len(stu)})
return(numStudents)
#CREATE XML FEED FILE
def create_xml(newStudents, sectionCount, cursor):
numSection = 1
maxEnroll = 20
print("new students", newStudents)
print("count", sectionCount)
#XML HEADER
top = Element('enterprise')
comment = Comment('XML to Process Sandbox Enrollments')
top.append(comment)
propertiesParent = SubElement(top, 'properties', {'lang':"EN"})
propertiesChildren = SubElement(propertiesParent, 'datasource')
propertiesChildren.text = "Campus Nexus"
propertiesChildren = SubElement(propertiesParent, 'target')
propertiesChildren.text = "UMA Blackboard"
propertiesChildren = SubElement(propertiesParent, 'type')
propertiesChildren.text = "XML"
#GET COUNT FOR SECTIONS FOUND FOR NEW STUDENTS (IF EXISTS)
for xsDate,sList in newStudents.items():
tmpSects = {k:v for k,v in sectionCount.items() if xsDate in k}
print("tempsects",tmpSects)
for stu in sList:
if all([v >= maxEnroll for v in tmpSects.values()]):
secNums = [int(k.split('_')[1]) for k in tmpSects.keys()]
numSection = max(secNums, default=0) + 1
print("numSection", numSection)
if numSection <= 9:
section = f'{xsDate}_00{numSection}'
else:
section = f'{xsDate}_0{numSection}'
tmpSects[section] = 1
print('section',section)
groupParent1 = SubElement(top, 'membership')
comment = Comment('Enroll users in the Sandbox section')
groupParent1.append(comment)
groupChild1 = SubElement(groupParent1, 'sourcedid')
groupChild1a = SubElement(groupChild1, 'source')
groupChild1a.text = "Campus Nexus"
groupChild1b = SubElement(groupChild1, 'id')
groupChild1b.text = section
groupChild2 = SubElement(groupParent1, 'member')
groupChild2a = SubElement(groupChild2, 'sourcedid')
groupChild2b = SubElement(groupChild2a, 'source')
groupChild2b.text = "Campus Nexus"
groupChild2b = SubElement(groupChild2a, 'id')
groupChild2b.text = "SyStudent_" + str(stu)
groupChild3 = SubElement(groupChild2, 'idtype')
groupChild3.text = '1'
groupChild4 = SubElement(groupChild2, 'role', roletype = '1')
groupChild5 = SubElement(groupChild4, 'status')
groupChild5.text = '1'
groupChild6 = SubElement(groupChild4, 'extension')
groupChild6a = SubElement(groupChild6, 'x_bb_available')
groupChild6a.text = 'Y'
groupChild6b = SubElement(groupChild6, 'x_bb_row_status')
groupChild6b.text = '0'
groupChild6c = SubElement(groupChild6, 'x_bb_datasource_key')
groupChild6c.text = 'MEMBERS.TXT'
else:
for k,v in tmpSects.items():
if v < maxEnroll:
numSection = int(k.split('_')[1])
if numSection <= 9:
section = f'{xsDate}_00{numSection}'
else:
section = f'{xsDate}_0{numSection}'
tmpSects[section] += 1
print(prettify(top))
#CONNECT TO SQL DATABASE
cnxn = pyodbc.connect("Driver={SQL Server Native Client 11.0};"
"Server=MLK-CVU-U-SQ02;"
"Database=FREEDOM;"
"Trusted_Connection=yes;")
cursor = cnxn.cursor()
newStudents = get_new_enrollments(cursor)
sectionCount = current_enrollment_count(cursor)
create_xml(newStudents, sectionCount, cursor)
cursor.close()
cnxn.close()
print("SQL connection closed.") This code currently generates the XML file as this:
Output: <?xml version="1.0" ?>
<enterprise>
<!--XML to Process Sandbox Enrollments-->
<properties lang="EN">
<datasource>Campus Nexus</datasource>
<target>UMA Blackboard</target>
<type>XML</type>
</properties>
<membership>
<!--Enroll users in the Sandbox section-->
<sourcedid>
<source>Campus Nexus</source>
<id>07292019_001</id>
</sourcedid>
<member>
<sourcedid>
<source>Campus Nexus</source>
<id>SyStudent_5764146</id>
</sourcedid>
<idtype>1</idtype>
<role roletype="1">
<status>1</status>
<extension>
<x_bb_available>Y</x_bb_available>
<x_bb_row_status>0</x_bb_row_status>
<x_bb_datasource_key>MEMBERS.TXT</x_bb_datasource_key>
</extension>
</role>
</member>
</membership>
<membership>
<!--Enroll users in the Sandbox section-->
<sourcedid>
<source>Campus Nexus</source>
<id>07292019_001</id>
</sourcedid>
<member>
<sourcedid>
<source>Campus Nexus</source>
<id>SyStudent_5764208</id>
</sourcedid>
<idtype>1</idtype>
<role roletype="1">
<status>1</status>
<extension>
<x_bb_available>Y</x_bb_available>
<x_bb_row_status>0</x_bb_row_status>
<x_bb_datasource_key>MEMBERS.TXT</x_bb_datasource_key>
</extension>
</role>
</member>
</membership>
</enterprise>
But it needs to format as this:
Output: <?xml version="1.0" ?>
<enterprise>
<!--XML to Process Sandbox Enrollments-->
<properties lang="EN">
<datasource>Campus Nexus</datasource>
<target>UMA Blackboard</target>
<type>XML</type>
</properties>
<membership>
<!--Enroll users in the Sandbox section-->
<sourcedid>
<source>Campus Nexus</source>
<id>07292019_001</id>
</sourcedid>
<member>
<sourcedid>
<source>Campus Nexus</source>
<id>SyStudent_5764146</id>
</sourcedid>
<idtype>1</idtype>
<role roletype="1">
<status>1</status>
<extension>
<x_bb_available>Y</x_bb_available>
<x_bb_row_status>0</x_bb_row_status>
<x_bb_datasource_key>MEMBERS.TXT</x_bb_datasource_key>
</extension>
</role>
</member>
<member>
<sourcedid>
<source>Campus Nexus</source>
<id>SyStudent_5764208</id>
</sourcedid>
<idtype>1</idtype>
<role roletype="1">
<status>1</status>
<extension>
<x_bb_available>Y</x_bb_available>
<x_bb_row_status>0</x_bb_row_status>
<x_bb_datasource_key>MEMBERS.TXT</x_bb_datasource_key>
</extension>
</role>
</member>
</membership>
</enterprise>
Any insight would be greatly appreciated!!
Posts: 3,458
Threads: 101
Joined: Sep 2016
I think you want this: groupParent1 = SubElement(top, 'membership') to be outside the for-loop, so there's only one of them.
Posts: 5
Threads: 1
Joined: Jun 2019
(Jul-29-2019, 04:20 PM)nilamo Wrote: I think you want this: groupParent1 = SubElement(top, 'membership') to be outside the for-loop, so there's only one of them.
Hi nilamo,
Thanks for the reply! Please note that I have only been programming in python for a year so am very new to all of the options available. So, I am grateful for any help and insight!
This is what I have so far after making changes based on changes in requirements:
import os
import sys
import pyodbc
import requests
from datetime import datetime as dt
from collections import defaultdict
from xml.dom import minidom
from xml.etree import ElementTree
from xml.etree.ElementTree import Element, SubElement, Comment
#GET LIST OF NEW ENROLLMENTS TO PROCESS
def get_new_enrollments(cursor):
SQL1 = "SELECT ExpectedStartDate, SyStudentID FROM [LMS_Data].[OrientationStudentInformation] WHERE OrientationSection IS NULL order by ExpectedStartDate asc"
cursor.execute(SQL1)
newEnrolls = cursor.fetchall()
newEnrollments = []
if not newEnrolls:
print("There are no new enrollments to process for Sandbox.")
sys.exit()
else:
for row in newEnrolls:
expStartDate = dt.strftime(row[0], '%m%d%Y')
row[0] = expStartDate
newEnrollments.append(row)
enrollmentDict = defaultdict(list)
for xsDate, syId in newEnrollments:
enrollmentDict[xsDate].append(syId)
return(enrollmentDict)
#RETURN A PRETTY-PRINTED XML STRING FOR THE FEEDFILE
def prettify(elem):
rough_string = ElementTree.tostring(elem, encoding='UTF-8')
reparsed = minidom.parseString(rough_string)
return(reparsed.toprettyxml(indent=" "))
#GET CURRENT COUNT OF ENROLLMENTS BY SECTION FROM DB TABLE
def current_enrollment_count(cursor):
SQL2 = ("SELECT OrientationSection, SyStudentID from [LMS_Data].[OrientationStudentInformation] where OrientationSection IS NOT NULL")
cursor.execute(SQL2)
currEnroll = cursor.fetchall()
sectionDict = {}
for section, student in currEnroll:
sectionDict.setdefault(section, []).append(student)
sectionCount = {}
for sec, stu in sectionDict.items():
sectionCount.update({sec: len(stu)})
return(sectionCount)
#CREATE XML FEED FILE
def create_xml(newStudents, numStudents, cursor):
#XML HEADER
top = Element('enterprise')
comment = Comment('XML to Process Sandbox Enrollments')
top.append(comment)
propertiesParent = SubElement(top, 'properties', {'lang':"EN"})
propertiesChildren = SubElement(propertiesParent, 'datasource')
propertiesChildren.text = "Campus Nexus"
propertiesChildren = SubElement(propertiesParent, 'target')
propertiesChildren.text = "UMA Blackboard"
propertiesChildren = SubElement(propertiesParent, 'type')
propertiesChildren.text = "XML"
#COUNT OF EXISTING STUDENTS IN EXISTING SECTIONS FOR NEW STUDENTS' START DATES
for xsDate,sList in newStudents.items():
tmpSects = {k:v for k,v in numStudents.items() if xsDate in k}
print("tempsects",tmpSects)
maxEnroll = 3
ctr = 0
insertData = []
for key in newStudents:
numSection = 1
if numSection <= 9:
section = f'CourseSandbox_{key}_00{numSection}'
else:
section = f'CourseSandbox_{key}_0{numSection}'
groupParent1 = SubElement(top, 'membership')
comment = Comment('Enroll users in the Sandbox section')
groupParent1.append(comment)
groupChild1 = SubElement(groupParent1, 'sourcedid')
groupChild1a = SubElement(groupChild1, 'source')
groupChild1a.text = "Campus Nexus"
groupChild1b = SubElement(groupChild1, 'id')
groupChild1b.text = section
#GENERATE XML BODY FOR ENROLLMENTS AND PARENT GROUPING FOR NEW SECTIONS CREATED
for value in range(len(newStudents[key])):
if ctr > maxEnroll - 1:
ctr = 0
numSection += 1
if numSection <= 9:
section = f'CourseSandbox_{key}_00{numSection}'
else:
section = f'CourseSandbox_{key}_0{numSection}'
groupParent1 = SubElement(top, 'membership')
comment = Comment('Enroll users in the Sandbox section')
groupParent1.append(comment)
groupChild1 = SubElement(groupParent1, 'sourcedid')
groupChild1a = SubElement(groupChild1, 'source')
groupChild1a.text = "Campus Nexus"
groupChild1b = SubElement(groupChild1, 'id')
groupChild1b.text = section
ctr += 1
groupChild2 = SubElement(groupParent1, 'member')
groupChild2a = SubElement(groupChild2, 'sourcedid')
groupChild2b = SubElement(groupChild2a, 'source')
groupChild2b.text = "Campus Nexus"
groupChild2b = SubElement(groupChild2a, 'id')
groupChild2b.text = "SyStudent_" + str(newStudents[key][value])
groupChild3 = SubElement(groupChild2, 'idtype')
groupChild3.text = '1'
groupChild4 = SubElement(groupChild2, 'role', roletype = '1')
groupChild5 = SubElement(groupChild4, 'status')
groupChild5.text = '1'
groupChild6 = SubElement(groupChild4, 'extension')
groupChild6a = SubElement(groupChild6, 'x_bb_available')
groupChild6a.text = 'Y'
groupChild6b = SubElement(groupChild6, 'x_bb_row_status')
groupChild6b.text = '0'
groupChild6c = SubElement(groupChild6, 'x_bb_datasource_key')
groupChild6c.text = 'MEMBERS.TXT'
insertData.append([groupChild1b.text, str(newStudents[key][value])])
numSection += 1
print(prettify(top)) So now I have to take into account any students already enrolled into existing sections. Then only add new ones. So, if the total number of enrollments per section is 20 and there are 20 enrollments in section 001 and 15 enrolled in section 002 and there are 10 new enrollments to process, I need to enroll the first 5 new users in section 002 and the remaining 5 in section 003.
I received the following piece of code from a "colleague" but have no idea how to incorporate it into my existing code or if it can even be used for my purposes. When I try to, it messes up the entire formatting of the XML file...again. Here is the codepiece:
if all([v >= maxEnroll for v in tmpSects.values()]):
secNums = [int(k.split('_')[1]) for k in tmpSects.keys()]
numSection = max(secNums, default=0) + 1 Again, any help is appreciated!!
Posts: 3,458
Threads: 101
Joined: Sep 2016
Looks like you're still generating multiple memberships. I thought you only wanted one?
Posts: 5
Threads: 1
Joined: Jun 2019
(Jul-29-2019, 08:29 PM)nilamo Wrote: Looks like you're still generating multiple memberships. I thought you only wanted one?
Hi nilamo,
The output needed is:
Output: <?xml version="1.0" ?>
<enterprise>
<!--XML to Process Sandbox Enrollments-->
<properties lang="EN">
<datasource>Campus Nexus</datasource>
<target>UMA Blackboard</target>
<type>XML</type>
</properties>
<membership>
<!--Enroll users in the Sandbox section-->
<sourcedid>
<source>Campus Nexus</source>
<id>CourseSandbox_08192019_001</id>
</sourcedid>
<member>
<sourcedid>
<source>Campus Nexus</source>
<id>SyStudent_5759242</id>
</sourcedid>
<idtype>1</idtype>
<role roletype="1">
<status>1</status>
<extension>
<x_bb_available>Y</x_bb_available>
<x_bb_row_status>0</x_bb_row_status>
<x_bb_datasource_key>MEMBERS.TXT</x_bb_datasource_key>
</extension>
</role>
</member>
<member>
<sourcedid>
<source>Campus Nexus</source>
<id>SyStudent_5759515</id>
</sourcedid>
<idtype>1</idtype>
<role roletype="1">
<status>1</status>
<extension>
<x_bb_available>Y</x_bb_available>
<x_bb_row_status>0</x_bb_row_status>
<x_bb_datasource_key>MEMBERS.TXT</x_bb_datasource_key>
</extension>
</role>
</member>
<member>
<sourcedid>
<source>Campus Nexus</source>
<id>SyStudent_5759552</id>
</sourcedid>
<idtype>1</idtype>
<role roletype="1">
<status>1</status>
<extension>
<x_bb_available>Y</x_bb_available>
<x_bb_row_status>0</x_bb_row_status>
<x_bb_datasource_key>MEMBERS.TXT</x_bb_datasource_key>
</extension>
</role>
</member>
</membership>
<membership>
<!--Enroll users in the Sandbox section-->
<sourcedid>
<source>Campus Nexus</source>
<id>CourseSandbox_08192019_002</id>
</sourcedid>
<member>
<sourcedid>
<source>Campus Nexus</source>
<id>SyStudent_5759554</id>
</sourcedid>
<idtype>1</idtype>
<role roletype="1">
<status>1</status>
<extension>
<x_bb_available>Y</x_bb_available>
<x_bb_row_status>0</x_bb_row_status>
<x_bb_datasource_key>MEMBERS.TXT</x_bb_datasource_key>
</extension>
</role>
</member>
<member>
<sourcedid>
<source>Campus Nexus</source>
<id>SyStudent_5759039</id>
</sourcedid>
<idtype>1</idtype>
<role roletype="1">
<status>1</status>
<extension>
<x_bb_available>Y</x_bb_available>
<x_bb_row_status>0</x_bb_row_status>
<x_bb_datasource_key>MEMBERS.TXT</x_bb_datasource_key>
</extension>
</role>
</member>
<member>
<sourcedid>
<source>Campus Nexus</source>
<id>SyStudent_5759043</id>
</sourcedid>
<idtype>1</idtype>
<role roletype="1">
<status>1</status>
<extension>
<x_bb_available>Y</x_bb_available>
<x_bb_row_status>0</x_bb_row_status>
<x_bb_datasource_key>MEMBERS.TXT</x_bb_datasource_key>
</extension>
</role>
</member>
</membership>
<membership>
<!--Enroll users in the Sandbox section-->
<sourcedid>
<source>Campus Nexus</source>
<id>CourseSandbox_08192019_003</id>
</sourcedid>
<member>
<sourcedid>
<source>Campus Nexus</source>
<id>SyStudent_5759044</id>
</sourcedid>
<idtype>1</idtype>
<role roletype="1">
<status>1</status>
<extension>
<x_bb_available>Y</x_bb_available>
<x_bb_row_status>0</x_bb_row_status>
<x_bb_datasource_key>MEMBERS.TXT</x_bb_datasource_key>
</extension>
</role>
</member>
<member>
<sourcedid>
<source>Campus Nexus</source>
<id>SyStudent_5759577</id>
</sourcedid>
<idtype>1</idtype>
<role roletype="1">
<status>1</status>
<extension>
<x_bb_available>Y</x_bb_available>
<x_bb_row_status>0</x_bb_row_status>
<x_bb_datasource_key>MEMBERS.TXT</x_bb_datasource_key>
</extension>
</role>
</member>
<member>
<sourcedid>
<source>Campus Nexus</source>
<id>SyStudent_5759036</id>
</sourcedid>
<idtype>1</idtype>
<role roletype="1">
<status>1</status>
<extension>
<x_bb_available>Y</x_bb_available>
<x_bb_row_status>0</x_bb_row_status>
<x_bb_datasource_key>MEMBERS.TXT</x_bb_datasource_key>
</extension>
</role>
</member>
</membership>
</enterprise>
But if there is an existing enrollment for the first section - CourseSandbox_08192019_001 - then it would only process two enrollments for this section since the max enrollment for a section in this code is 3.
Sorry if I am not explaining properly.
|