Replacing a component in a Flowchart
Posted: Tue Aug 05, 2025 1:01 pm
I recently hit upon a situation where I needed to replace one component in a Flowchart with a different one.
This can be done by finding each macro in the component and modifying it by hand.
It can be done by using 'Replace' - but only if the components are compatible (I didn't manage to get this to work - using two displays with Initialise called on one - attempting to change to the other display gave a 'this will lead to errors' message)
Being lazy - I wrote a small Python script to do the hard work
So using (for example) - a Flowchart (Flowcode1.fcfx) with two components - one with handle 'gLCD_SSD1306_i2c1' that I want to replace with gLCD_ST7565R1.
On a command line I do:
python component.py Flowcode1 NewFile gLCD_SSD1306_i2c1 gLCD_ST7565R1
which reads Flowcode1.fcfx and outputs a new file NewFile.fcfx with gLCD_SSD1306_i2c1 replaced by gLCD_ST7565R1 - I can then edit NewFile and delete the unused component. Any compatibility issues (different number of arguments or missing macros) will be highlighted as an error - and can be corrected.
Note that NewFile.fcfx will be overwritten if it already exists (and if you set to be the same as input will overwrite that - but check results first !! )
You will need to have python3 installed.
Save the code as 'component.py' (or name.py of your choice)
You will need BeautifulSoup and lxml (pip install bs4 lxml)
Anyone who tries this - please let us know how you get on...
Martin
This can be done by finding each macro in the component and modifying it by hand.
It can be done by using 'Replace' - but only if the components are compatible (I didn't manage to get this to work - using two displays with Initialise called on one - attempting to change to the other display gave a 'this will lead to errors' message)
Being lazy - I wrote a small Python script to do the hard work

So using (for example) - a Flowchart (Flowcode1.fcfx) with two components - one with handle 'gLCD_SSD1306_i2c1' that I want to replace with gLCD_ST7565R1.
On a command line I do:
python component.py Flowcode1 NewFile gLCD_SSD1306_i2c1 gLCD_ST7565R1
which reads Flowcode1.fcfx and outputs a new file NewFile.fcfx with gLCD_SSD1306_i2c1 replaced by gLCD_ST7565R1 - I can then edit NewFile and delete the unused component. Any compatibility issues (different number of arguments or missing macros) will be highlighted as an error - and can be corrected.
Note that NewFile.fcfx will be overwritten if it already exists (and if you set to be the same as input will overwrite that - but check results first !! )
Code: Select all
import argparse
from bs4 import BeautifulSoup
def replace_component_in_xml(file_path, new_path, old_value, new_value):
"""
Reads an XML file, finds all <macro> tags where the 'component' attribute
matches old_value, and replaces it with new_value.
Args:
file_path (str): The path to the input XML file.
new_path (str): Output as new file
old_value (str): The component value to search for.
new_value (str): The new value to replace the old_value with.
"""
try:
# Step 1: Read the XML file
with open(file_path, 'r', encoding='utf-8') as file:
content = file.read()
# Step 2: Parse the XML with BeautifulSoup
soup = BeautifulSoup(content, 'xml')
# Step 3: Find all matching nodes
nodes_to_update = soup.find_all('command', component=old_value)
if not nodes_to_update:
print(f"No <macro> nodes with component='{old_value}' found. No changes made.")
return
# Step 4: Iterate and replace the attribute value
for tag in nodes_to_update:
original_tag = str(tag)
tag['component'] = new_value
print(f"Found and replaced: {original_tag} -> {str(tag)}")
# Step 5: Write the changes back to the file
with open(new_path, 'w', encoding='utf-8') as file:
file.write(str(soup.prettify()))
print(f"\nSuccessfully updated {len(nodes_to_update)} node(s) in {file_path} - saved as {new_path}.")
except FileNotFoundError:
print(f"Error: The file '{file_path}' was not found.")
except Exception as e:
print(f"An unexpected error occurred: {e}")
def main():
"""
Sets up command-line argument parsing and calls the main function.
"""
# Initialize the parser
parser = argparse.ArgumentParser(
description="Replaces the 'component' attribute value in <macro> tags of an XML file."
)
# Add the arguments we expect
parser.add_argument("file_path", help="The path to the Flowcode file to process.")
parser.add_argument("out_path", help="The new file to save Flowchart as")
parser.add_argument("old_value", help="The current component value to be replaced (e.g., 'abc').")
parser.add_argument("new_value", help="The new component value to set (e.g., 'Def').")
# Parse the arguments from the command line
args = parser.parse_args()
# Call the main processing function with the parsed arguments
replace_component_in_xml(args.file_path + ".fcfx", args.out_path + ".fcfx", args.old_value, args.new_value)
if __name__ == "__main__":
main()
Save the code as 'component.py' (or name.py of your choice)
You will need BeautifulSoup and lxml (pip install bs4 lxml)
Anyone who tries this - please let us know how you get on...
Martin