-1

I have some XML files that i want to sort by the element name. These xml files are considered used as Profiles in my salesforce sandbox/org. Ive built some code that takes an xml file and appends it to the bottom of each profile xml file.Allowing me to add code to multiple files all at once rather than having to copy/paste to each file. The issue here, the xml needs to be sorted alphabetically by the element name, ex:(classAccesses, fieldPermissions, layoutAssignments, recordTypeVisibilities, objectPermissions) I have pasted an example of the xml below. The format of the file needs to be consistent and cant change as salesforce might not like it.

<?xml version="1.0" encoding="UTF-8"?>
<Profile xmlns="http://soap.sforce.com/2006/04/metadata">
    <fieldPermissions>
        <editable>false</editable>
        <field>Branch_Queue__c.Cell_Phone_Number__c</field>
        <readable>true</readable>
    </fieldPermissions>
    <fieldPermissions>
        <editable>false</editable>
        <field>Branch_Queue__c.Branch__c</field>
        <readable>true</readable>
    </fieldPermissions>
    <fieldPermissions>
        <editable>false</editable>
        <field>Branch_Queue__c.Source__c</field>
        <readable>true</readable>
    </fieldPermissions>
    <fieldPermissions>
        <editable>false</editable>
        <field>Branch_Queue__c.Served_By__c</field>
        <readable>true</readable>
    </fieldPermissions>
    <fieldPermissions>
            <editable>false</editable>
            <field>Branch_Queue__c.Update__c</field>
            <readable>true</readable>
    </fieldPermissions>
    <recordTypeVisibilities>
        <default>false</default>
        <recordType>Knowledge__kav.RealEstate</recordType>
        <visible>true</visible>
    </recordTypeVisibilities>
    <recordTypeVisibilities>
        <default>false</default>
        <recordType>Knowledge__kav.RealEstate_Community_Connection</recordType>
        <visible>true</visible>
    </recordTypeVisibilities>
     <objectPermissions>
        <allowCreate>false</allowCreate>
        <allowDelete>false</allowDelete>
        <allowEdit>false</allowEdit>
        <allowRead>true</allowRead>
        <modifyAllRecords>false</modifyAllRecords>
        <object>Branch_Queue__c</object>
        <viewAllRecords>true</viewAllRecords>
    </objectPermissions>
    <classAccesses>
        <apexClass>BranchQueueDisplayList</apexClass>
        <enabled>true</enabled>
    </classAccesses>
    <classAccesses>
        <apexClass>BranchQueueDisplayList_Test</apexClass>
        <enabled>true</enabled>
    </classAccesses>
    <classAccesses>
        <apexClass>BranchQueueService</apexClass>
        <enabled>true</enabled>
    </classAccesses>
</Profile>

if it helps, here is the python script i have built. if you have any questions please feel free to ask. Thanks!

import os 
import json
directory = 'C:/Users/HB35401/MAXDev/force-app/main/default/profiles' #folder containing profiles to be modified
os.chdir(directory)
newData = 'C:/testXMLBatch/additionalXML/addXML.xml' #xml file to append to profile-xml files.

for nameOfFile in os.listdir(directory): #for each profile in the directory
    if nameOfFile.endswith(".xml"):
        g = open(newData)
        data = g.read() #set the value of the newXML to the data variable
        f = open(nameOfFile)
        fileContent = f.read() #save the content of the profile to fileContent
        if data in fileContent:
            print('ERROR: XML is already inside the Profile.' + nameOfFile)
        else:
            EndLine = fileContent[-11:] #save the </Profile> tag from the bottom of the file to EndLine variable.
            #print(EndLine)            # theEndLine will be appended back after we add our new XML.
            test = fileContent[:-11] #remove the </Profile> tag and write back to the profile the removal of the </Profile> tag
            with open(nameOfFile, "w") as w:
                w.write(test)
            with open(nameOfFile) as t:
                fileContent2 = t.read()
                #print(fileContent2)   

            h = open(nameOfFile, "a") #add the new data to the profile along with the </Profile> tag
            h.write(data + "\n"+ EndLine)
            h.close()
  • 2
    Have you attempted any sorting yourself? The code in the question seems unrelated to sorting. – mzjn Jul 29 '20 at 17:10
  • @mzjn Ive attempted some sorting from a few api i found online but no luck. I'm new to python and my google searches havent proven to beneficial. I want to loop through the xml and grab all of the elements with their contents but i cant find how to do that. – Kevin Every Jul 29 '20 at 17:54
  • 1
    @KevinEvery _I want to loop through the xml and grab all of the elements with their contents but i cant find how to do that._ That's a different question, then. You should look into XML parsing with Python first. – AMC Jul 29 '20 at 18:10

1 Answers1

0

Try this .

from simplified_scrapy import SimplifiedDoc, utils
xml = utils.getFileContent('your xml file.xml')
doc = SimplifiedDoc(xml)
root = doc.Profile
nodes = root.children # Get all nodes

count = len(nodes)
if count:
    sorted_nodes = sorted(nodes, key=operator.itemgetter('tag')) # Sort by tag
    sorted_htmls = []
    for node in sorted_nodes:
        sorted_htmls.append(node.outerHtml) # Get the string of sorted nodes
    for i in range(0, count):
        nodes[i].repleaceSelf(sorted_htmls[i]) # Replace the nodes in the original text with the sorted nodes

print(doc.html)
dabingsou
  • 2,469
  • 1
  • 5
  • 8