Dynamically changing SVG element stroke via scripting

Hi All,

I am trying to set a stroke property of an svg based on the element name.
i can parse the structure and get the correct property path but cant seem to set the property value.

def transform(self, value, quality, timestamp):
	row = value.split('B')[0]
	root = self.getChild("root").getChild("WarehouseLocation").props.elements[1].elements
	returnParam=''
	for x in range(len(root)):
		if root[x]['id'] == row:
			
			for y in range(len(root[x]['elements'])):
				if root[x]['elements'][y]['id'] ==value:
					returnParam += "["+str(x) +"].elements["+str(y)+"].stroke.paint"
	
	#This returns (as a string) self.getChild("root").getChild("WarehouseLocation").props.elements[1].elements[10].elements[3].stroke.paint			
	'self.getChild("root").getChild("WarehouseLocation").props.elements[1].elements' + returnParam = '#00FF00'
	

any thoughts about setting this string which is the property we want to change?

Hello Andrew,

You can try using exec to compile your path and set it's value.

Eww, no, don't ever use exec or eval.
In this particular case, just store the indices you care about in separate variables:

def transform(self, value, quality, timestamp):
	row = value.split('B')[0]
	root = self.getChild("root").getChild("WarehouseLocation").props.elements[1].elements
	returnParam=''

	xIndex = None
	yIndex = None
	for x in range(len(root)):
		if root[x]['id'] == row:
			for y in range(len(root[x]['elements'])):
				if root[x]['elements'][y]['id'] ==value:
					yIndex = y
					xIndex = x

	if xIndex is not None:
		self.getChild("root").getChild("WarehouseLocation").props.elements[1].elements[xIndex].elements[yIndex].stroke.paint = '#00FF00'

I have a Vision script I am developing to build a dataset with string component paths that can be nested to any depth, and I had intended to use eval to get the components using these paths. Is there a problem with doing this?

Is it something that could be done with getattr? I'd have to see the snippet to say for sure.

In general, it's the same risk as sql injection; if you're accepting user input, it's a bad idea. It's also awful for performance, though that's very unlikely to really matter here.

2 Likes

Thanks, that makes sense. This script is back end and not affected by user input, but I am curious if there is a better way. However, to avoid dragging this thread too far off of topic, I've created a separate thread here to discuss this matter in more detail:

1 Like