lutaml-model 0.8.32 → 0.8.33

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0a0c1ee735ac6b12da331e1f43dc6617d05cfe18534dc5255aaba0c789ee601e
4
- data.tar.gz: bde4936c85167bcec7a4618cd8e91c9c4cf65d2feb97b0d94c78bf368f085248
3
+ metadata.gz: 559deafaf5121c17a2703c362f355feb440380ba2f80fbb0ff9afa5440995841
4
+ data.tar.gz: 48ea3bfb26265e940cc54d88e49ce60b54887b7a52372e7e174284625185f88a
5
5
  SHA512:
6
- metadata.gz: 773ec772915ec1fd0645d68fa2e62c50bea3af147b19c67c22e5bd16cf1f6dec2a00bc1ff1945e612a7a6f5d22ce404d3e9687fead480d54390a847908e6d804
7
- data.tar.gz: 318c31871e7bbb83bd1bea6547f3dbeda4e1768da9d44f0e85c7434bd8db15ade859bdf9a909771126b33a85e345bc1e803a93eacdec2e557a51d39bf0e6f8cb
6
+ metadata.gz: a28e6ef895329e27e3796266c197b700a391df1aa0b8c8cdf4ed89c3c0e4016d876c92053481a2b6f118817327213445e88e7f9ea9c4f3e7c2b5d3b8465052b1
7
+ data.tar.gz: e87f3702b6e783da4be97faeae5a7a0c572cd05995d4a7f15d73d9784d8ead92bddcb696c12c584b372ff603fb6a94dbfd1ef21eb63c33bfd4da69569ecd9349
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Lutaml
4
4
  module Model
5
- VERSION = "0.8.32"
5
+ VERSION = "0.8.33"
6
6
  end
7
7
  end
@@ -469,7 +469,31 @@ _effective_register)
469
469
  end
470
470
  end
471
471
 
472
- def value_for_xml_attribute(doc, rule, rule_names)
472
+ # Whether no OTHER attribute rule in the mapping claims the same
473
+ # local name. A sole claimant is namespace-flexible on the local-
474
+ # name fallback: real-world documents qualify such attributes in
475
+ # the element's namespace, a foreign extension namespace, or not
476
+ # at all (OOXML w:val on w15: elements — lutaml-model#790). When
477
+ # a sibling claims the name, matching stays strict so each rule
478
+ # keeps its own namespace (#744, #758).
479
+ def attribute_rule_sole_local_claimant?(instance, rule,
480
+ effective_register)
481
+ klass = instance.class
482
+ return true unless klass.include?(Lutaml::Model::Serialize)
483
+
484
+ mapping = klass.mappings_for(:xml, effective_register)
485
+ return true unless mapping
486
+
487
+ expected = Array(rule.name).map(&:to_s)
488
+ mapping.mappings.none? do |sib|
489
+ next false unless sib.attribute? && !sib.equal?(rule)
490
+
491
+ Array(sib.name).map(&:to_s) == expected
492
+ end
493
+ end
494
+
495
+ def value_for_xml_attribute(doc, rule, rule_names,
496
+ flexible_local: false)
473
497
  # For attributes, rule_names may contain namespaced names, but find_attribute_value
474
498
  # expects prefix:name or just name, so we need to convert namespaced names to prefix format.
475
499
  #
@@ -496,7 +520,8 @@ _effective_register)
496
520
  # This handles the case where the namespace prefix is not declared in the document
497
521
  # (e.g., v:ext without xmlns:v="...").
498
522
  if value.nil? && rule_names.any? { |rn| rn.include?(":") }
499
- value = find_attribute_by_local_name(doc, rule_names)
523
+ value = find_attribute_by_local_name(doc, rule_names,
524
+ flexible_local: flexible_local)
500
525
  end
501
526
 
502
527
  value = value&.split(rule.delimiter) if rule.delimiter
@@ -559,7 +584,8 @@ _effective_register)
559
584
  # @param doc [XmlElement] the parsed XML document root
560
585
  # @param rule_names [Array<String>] the rule names to match
561
586
  # @return [String, nil] the attribute value or nil
562
- def find_attribute_by_local_name(doc, rule_names)
587
+ def find_attribute_by_local_name(doc, rule_names,
588
+ flexible_local: false)
563
589
  rule_names.each do |rn|
564
590
  next unless rn.include?(":")
565
591
 
@@ -579,7 +605,12 @@ _effective_register)
579
605
  # namespaced sibling attribute (lutaml-model#758). An
580
606
  # XmlAttribute with a resolved namespace has namespaced_name
581
607
  # "URI:local", so this comparison is allocation-free.
582
- if attr.namespace.nil?
608
+ if flexible_local
609
+ # Sole claimant: any qualification of the local name binds
610
+ # (element namespace, foreign extension namespace, none).
611
+ attr.unprefixed_name == local_name ||
612
+ ((colon = attr.name.rindex(":")) ? attr.name[(colon + 1)..] : attr.name) == local_name
613
+ elsif attr.namespace.nil?
583
614
  next false if attr.namespace_prefix.nil? &&
584
615
  !attr.name.include?(":")
585
616
 
@@ -630,7 +661,14 @@ _effective_register)
630
661
  # return the same children again.
631
662
  rule_names = rule_names.concat(extra_rule_names).uniq if extra_rule_names
632
663
 
633
- return value_for_xml_attribute(doc, rule, rule_names) if rule.attribute?
664
+ if rule.attribute?
665
+ return value_for_xml_attribute(
666
+ doc, rule, rule_names,
667
+ flexible_local: attribute_rule_sole_local_claimant?(
668
+ instance, rule, effective_register
669
+ )
670
+ )
671
+ end
634
672
 
635
673
  # Performance: Pre-compute type-related values used in the hot loop
636
674
  attr_type_is_serializable = attr_type && attr_type <= ::Lutaml::Model::Serialize
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lutaml-model
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.32
4
+ version: 0.8.33
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.