Open-XML-SDK
Open-XML-SDK copied to clipboard
Investigate changing extensionlist/extension mechanism naming to more closely match Office use
History
Office team provides CT_ExtensionList and CT_Extension types in xsd definitions and uses a uri attribute in the new child elements under CT_Extension to authorize the relationship between the child and parent.
<x:tableColumn id="1" xr3:uid="{00000000-0010-0000-0000-000001000000}" name="Id" dataDxfId="11">
<x:extLst>
<x:ext xmlns:xlmsforms="http://schemas.microsoft.com/office/spreadsheetml/2023/msForms" uri="{FCC71383-01E1-4257-9335-427F07BE8D7F}">
<xlmsforms:question id="id"></xlmsforms:question>
</x:ext>
</x:extLst>
</x:tableColumn>
In the backend of the SDK (not seen to the public), we have been using specialized CT_<feature>ExtensionList/CT_<feature>Extension complex types to generate C# classes which emit the same structure as above but provide this parent/child relationship authorization at compile time with strong typing instead of runtime via guids.
NOTE:
By creating specialized CT_<feature>ExtensionList/CT_<feature>Extension derived C# classes, we created mutual exclusivity between the CT_Extension* derived properties that exist before extending the parent type and the new specialized CT_<feature>Extenstion* properties that we build after Office extends the parent type.
The exclusivity, comes from the fact that both the CT_Extension* and CT_<feature>Extenstion* represent the same element as derived from OpenXmlCompositeElement. Because of this exclusivity, when we release a new child extension, we replace the existing CT_Extension* property in the parent with the new CT_<feature>Extension* property.
This replacement sometimes represents a breaking change in the SDK framework API. In order to maintain semantic versioning we would have to maintain both CT_Extension* and CT_<feature>Extenstion* properties in the extended parent type and create a shim or migration pathway from the old to the new (until a major version).
Problem Statement
Avoid introducing a breaking change.
...when we release a new child extension, we replace the existing CT_Extension* property in the parent with the new CT_<feature>Extension* property.
To qualify this, only when we release a new child extension to a type that has never had a child extension added by Office.
Approaches
One-time Refactor
One approach to this would be to replace all existing references to CT_ExtensionList and CT_Extension in the base Office xsds used by the SDK with CT_<feature>ExtensionList and CT_<feature>Extension appropriate to their use in the parent types. This would provide the extension list structure to allow new children extension elements to be added without breaking the SDK API going forward. This approach would require a one-time breaking change across the SDK but would avoid breaking changes going forward. If Office introduces a new parent type or adds a parent type with a CT_ExtensionList property, we could intercept that before it releases as an SDK class and change it to the CT_<feature>ExtensionList model.
Redesign To Use CT_Extension*
This involves redesigning the SDK validation, particle and element production and consumption processing code to use the Office method of Uri guids to determine parent/extension child relationships at runtime and move away from strong type enforcement.