You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Attribute identity is (namespace URI, local name): remove local-name conflation from lenient matching and candidate arrays #841
Attribute identity is (namespace URI, local name). Two attributes with different identity are different attributes — always. Two attributes with the same identity on one element are not well-formed XML (Unique Att Spec) and are rejected by the parser. There is no third case.
Corollary per Namespaces in XML: the default namespace never applies to attributes — an unprefixed attribute is always in no namespace, even when the document's xmlns is the namespace the producer "meant". So type can never bexmi:type; a producer intending the XMI-namespaced attribute must use a prefix.
Where we conflate today (to remove)
Lenient local-name fallbacks (find_attribute_by_local_name): match by local part across namespaces — distinct attributes collapse when a rule probes by bare name. Undeclared-prefix recovery (Lenient parsing of out-of-namespace documents silently drops elements (gml:description vanishes on round-trip) #754) is the one legitimate use; beyond that, a multi-match is an ambiguity, and should surface as such rather than silently resolve (today: order-of-attributes-dependent).
Candidate-array resolution in find_attribute_value(Array): rule spellings are resolved first-array-match; Fix attribute name in document order #837 proposes document-order-last. Both are resolution policies for what should be exact namespaced-name rules. Under exact identity, an element matching two candidates is a mapping ambiguity, not a choice to arbitrate by position or array order.
The motivating case (ea / XMI)
xmi:type (metaclass discriminator, XMI namespace) and type (classifier reference, no namespace) are different attributes. EA's ownedParameter profile writes only type; standard UML XMI writes xmi:type. Consumers should declare two exact rules and get both attributes distinctly — the ea gem currently carries a serialization-time regex (plain_parameter_type) solely because the model layer collapses them into one slot.
Proposal
Mapping rules are exact: map_attribute binds to (namespace URI, local name) — prefix-independent (the URI is the identity; the document's prefix spelling is not).
Lenient local-name matching is a recovery mechanism only: fires solely for the undeclared-prefix case; when a lenient probe matches MORE THAN ONE distinct attribute, return/signal ambiguity (log + no value, or a strict-mode error) instead of picking one.
find_attribute_value(Array) semantics: keep for alias lists where at most one alias can exist (spelling variants of one name); document that two simultaneous matches are an authoring error and surface them.
Consumers (ea/xmi gem) declare xmi:type and type as separate rules; the single-slot collapse and its regex workaround retire.
Non-goals
Document-order or array-order arbitration of conflated matches (treats the symptom; makes collapse deterministic instead of absent).
Supporting "attributes in the default namespace" — not expressible in XML.
Implemented and shipped. The lenient local-name probe is a recovery mechanism only — it fires solely for the namespaced-rule undeclared-prefix case, and when a probe matches more than one distinct attribute the matcher binds no value and surfaces the ambiguity (see match_attribute_by_local_name in lib/lutaml/xml/model_transform.rb, which carries this issue's identity principle). Alias-list resolution likewise surfaces simultaneous matches instead of arbitrating by array order (find_attribute_value in lib/lutaml/xml/xml_element.rb). Coverage: spec/lutaml/xml/attribute_ambiguity_surface_spec.rb — 22 examples green. The ea/xmi single-slot collapse and its regex workaround are retired in the ea gem's mapping work. Closing.
Principle
Attribute identity is (namespace URI, local name). Two attributes with different identity are different attributes — always. Two attributes with the same identity on one element are not well-formed XML (Unique Att Spec) and are rejected by the parser. There is no third case.
Corollary per Namespaces in XML: the default namespace never applies to attributes — an unprefixed attribute is always in no namespace, even when the document's
xmlnsis the namespace the producer "meant". Sotypecan never bexmi:type; a producer intending the XMI-namespaced attribute must use a prefix.Where we conflate today (to remove)
find_attribute_by_local_name): match by local part across namespaces — distinct attributes collapse when a rule probes by bare name. Undeclared-prefix recovery (Lenient parsing of out-of-namespace documents silently drops elements (gml:description vanishes on round-trip) #754) is the one legitimate use; beyond that, a multi-match is an ambiguity, and should surface as such rather than silently resolve (today: order-of-attributes-dependent).find_attribute_value(Array): rule spellings are resolved first-array-match; Fix attribute name in document order #837 proposes document-order-last. Both are resolution policies for what should be exact namespaced-name rules. Under exact identity, an element matching two candidates is a mapping ambiguity, not a choice to arbitrate by position or array order.The motivating case (ea / XMI)
xmi:type(metaclass discriminator, XMI namespace) andtype(classifier reference, no namespace) are different attributes. EA's ownedParameter profile writes onlytype; standard UML XMI writesxmi:type. Consumers should declare two exact rules and get both attributes distinctly — theeagem currently carries a serialization-time regex (plain_parameter_type) solely because the model layer collapses them into one slot.Proposal
map_attributebinds to (namespace URI, local name) — prefix-independent (the URI is the identity; the document's prefix spelling is not).find_attribute_value(Array)semantics: keep for alias lists where at most one alias can exist (spelling variants of one name); document that two simultaneous matches are an authoring error and surface them.xmi:typeandtypeas separate rules; the single-slot collapse and its regex workaround retire.Non-goals