dave-howard / vsdx

vsdx - A python library for processing .vsdx files
BSD 3-Clause "New" or "Revised" License
67 stars 25 forks source link

Exporting attributes of shapes #20

Closed frankhefner closed 2 years ago

frankhefner commented 3 years ago

Hi, I am quite new to this library. I do have the task to export the attributes of any shape from a Visio file. For now I do not have found any function within class vsdx.VisioFile.Shape that would allow looping over the attributes.

My code is as follows:

_from vsdx import VisioFile with VisioFile('Test_Prozess_neu.vsdx') as vis:

open first page

page = vis.get_page(0)
# Read all shapes
shapes = page.shapes[0].sub_shapes()
# Loop over all available shapes
for shape in shapes:
    print(shape.text)
    print(shape.ID)
    # Now I would normally execute the function for exporting all attributes...__

Do I do something wrong or does this function simply not exist (yet)?

Thanks for some support, Frank

dave-howard commented 3 years ago

Hi Frank - always good to see people using this :)

Just want to check what sort of attributes you mean - i.e. VisioFile.Shape object fields/properties or attributes of the original shape in Visio.

For the VIsioFIle.Shape object you can list attributes using shape.__dict__

So something like print(f"shape {shape.ID} {shape.__dict__}") in your loop

You might notice the the Shape.cells property when you do that, which provides a list of many of the attributes within the original Visio shape as in truncated example below:

'cells': {'PinX': Cell: name=PinX val=4.133858135787355 func=None, 'PinY': Cell: name=PinY val=10.65551182326173 func=None, 'Width': Cell: name=Width val=2.165354297053872 func=None .... and so on

Some of these have dedicated properties for getting/setting, like x and y, but many do not.

I hope that helps

Regards Dave

frankhefner commented 3 years ago

Hi Dave, Thanks for the prompt reply! I have tested the list attributes function shape.dict but unfortunatelly it is not showing the attributes/data of the shapes I am trying to get. I am searching for the data/attribute fields that I can view or define when I do a right click upon a shape, then choose "Data" -> "Shape Data" or "Data" -> "Define Shape Data". Please see attached screen shot. And sorry for the german language ;-) Any ideas how I can extract this kind of information from the Visio file?

Regards, Frank

Visio_Shape_Data

dave-howard commented 3 years ago

I see what you mean now - let me look into that

dave-howard commented 3 years ago

Hello Frank - I have just released v0.4.7, which introduces ShapeProperty class, a list of these being available from Shape.data_properties property. This is a basic initial implementation - it is lacking any specific consideration of master shape inheritence and of the value type (all values will be strings). You might want to look at the test method: test_get_shape_data_properties() for guidance. I hope this helps with what you were trying to do, Kind regards Dave

frankhefner commented 3 years ago

Hi Dave, sorry for coming back that late upon this. I have installed the new version and looked into the mentioned test method.

This is my code:

process properties

shapeProps = shape.data_properties

loop over the properties

for prop in shapeProps: print("Property value: " + str(prop.value))

The loop does at least provide the correct amount of properties, being set on a shape. But I do struggle with getting the property_name and property_value. The function prop.value always returns "None".

Would you have any advice for me, how to query the name and value of the property? Does it have something to do with the dictionary that you are passing to the function as a parameter?

Thanks in advance.

Regards, Frank

dave-howard commented 3 years ago

Hi Frank - looks like a bug in the library code (and test for this feature) rather than anything you are doing wrong. The fix is included in release v0.4.9 that I have just pushed here and to PyPI. I'll re-open this issue so we can close when properly resolved.

dave-howard commented 3 years ago

Hi Frank - just a heads up that I will change the Shape.data_properties type from list to dict in the next release, so just be aware of that. The reason for this is to make it easier to get a specific property from a shape e.g. my_shape.data_properties['my_prop_name'].value

frankhefner commented 3 years ago

Hi Dave, Thanks for taking care and for the heads up. I am going to test v0.4.9 next week.

Have a nice weekend, Frank

frankhefner commented 3 years ago

Hi Dave, I do have tested now v0.4.10. We are almost there but I would need a last information from you. When iterating over the data properties with the following code, I do only get the last data property as output.

for key, dataProperty in shape.data_properties.items(): print(dataProperty.getattribute('name'), '->', dataProperty.getattribute('value'))

Do I have to develop the loop differently or is the dictionary only having one item?

Regards, Frank

dave-howard commented 3 years ago

Hi Frank - that code seems valid, it does loop through two data items in the test file.

If I add it to test test_get_shape_data_properties() it runs fine and adds the expected output lines below...

my_property_name -> property value my_second_property_name -> another value

Note: The properties dict is indexed by label, not name - this is because the label is visible without opening the define data popup in Visio so it's a more convenient label for a shape - do your properties have labels?

it's unrelated, but you can also loop through as below:

for prop in shape.data_properties.values():
    print(prop.name, prop.value)

Dave

frankhefner commented 3 years ago

Hi Dave, You are right, the code works perfect for all new defined data properties on a shape. However, in my test file I have used a master shape that already had defined some data properties . If I enter some text to all data properties of the master shape, only the "last" one is being shown.

I would like to attach my test Visio file here, but github does not allow for uploading Visio files. So, I do only attach a screen-shot that shows the master shape and its data properties. Master_shape_data_properties

If I loop through the data properties of the master shape "shape.master_shape.items()" then I do get all data properties, but not the values. Would you have another hint for me, how to get all values of any data property of the master shape?

Ciao, Frank

dave-howard commented 3 years ago

That makes complete sense now :) I didn't take account of master shape properties - I've updated and release v0.4.11 and hopefully this will now work as expected.

Thanks Dave

frankhefner commented 2 years ago

Hi Dave, I have installed release v0.4.11 and tested it with my Visio test file. The result is still the same:

Shape_properties_v_0_4_11

When looking at the list of the shape properties it is showing all properties from the master shape and then it is repeating the last property having a value set. In my case the last property with a value is "Status".

Any further ideas from your side?

Cheers, Frank

dave-howard commented 2 years ago

Hi Frank,

You've highlighted a bug in how I was getting value of properties defined in a master shape but overirdden in the child shape.

(hence this comment is now much shorter)

Hopefully fixed this time in v0.4.13!

Cheers Dave

frankhefner commented 2 years ago

Hi Dave, good news, now it is working perfectly! Shape_properties_v_0_4_13_working_perfect

Thanks for all of your efforts and support!

Have a great week, Frank

dave-howard commented 2 years ago

Great news, took a few attempts but learned a bit along the way so always worthwhile :)

Thanks for comfirming so quick Frank

Cheers Dave