From 96661756b1f15a248857b28a861426761ca899e5 Mon Sep 17 00:00:00 2001 From: Lars Hesel Christensen Date: Fri, 10 Jan 2025 14:36:31 +0100 Subject: [PATCH] Fix sequence numbering in choice with sequences with complexTypes The sequence numbering was resent within the complexType handling and this change attempts to preserve the sequence numbering across the elements in the choice alternative handling. --- priv/choice_complex/choice_complex.xml | 5 +++++ priv/choice_complex/choice_complex.xsd | 24 ++++++++++++++++++++++++ src/erlsom_compile.erl | 23 ++++++++++------------- test/erlsom_tests.erl | 6 ++++++ 4 files changed, 45 insertions(+), 13 deletions(-) create mode 100644 priv/choice_complex/choice_complex.xml create mode 100644 priv/choice_complex/choice_complex.xsd diff --git a/priv/choice_complex/choice_complex.xml b/priv/choice_complex/choice_complex.xml new file mode 100644 index 0000000..8de1595 --- /dev/null +++ b/priv/choice_complex/choice_complex.xml @@ -0,0 +1,5 @@ + + + text + + diff --git a/priv/choice_complex/choice_complex.xsd b/priv/choice_complex/choice_complex.xsd new file mode 100644 index 0000000..8684eaa --- /dev/null +++ b/priv/choice_complex/choice_complex.xsd @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/src/erlsom_compile.erl b/src/erlsom_compile.erl index 42fdc01..2457904 100644 --- a/src/erlsom_compile.erl +++ b/src/erlsom_compile.erl @@ -784,24 +784,21 @@ isAny(#alt{tag = '#any', anyInfo = #anyInfo{prCont = "lax", ns = "##any"}}) -> isAny(_) -> false. -%% TODO: seqCnt should be passed from one element to the next, but not down into the -%% tree (it should be reset to 0) (the first sequence-in-sequnce should always have nr. 1). -%% -record(localElementType, {name, type, ref, minOccurs, maxOccurs, simpleOrComplex}). translateSequence([LocalElement = #localElementType{} |Tail], ElementsSoFar, Acc) -> - {Element, Acc2} = translateLocalElement(LocalElement, Acc), - translateSequence(Tail, [Element | ElementsSoFar], Acc2); + {Element, Acc2} = translateLocalElement(LocalElement, Acc#p1acc{seqCnt = 0}), + translateSequence(Tail, [Element | ElementsSoFar], Acc2#p1acc{seqCnt = Acc#p1acc.seqCnt}); translateSequence([ChoiceElement = #choiceType{} |Tail], ElementsSoFar, Acc) -> - {Element, Acc2} = translateElement(ChoiceElement, Acc), - translateSequence(Tail, [Element | ElementsSoFar], Acc2); + {Element, Acc2} = translateElement(ChoiceElement, Acc#p1acc{seqCnt = 0}), + translateSequence(Tail, [Element | ElementsSoFar], Acc2#p1acc{seqCnt = Acc#p1acc.seqCnt}); translateSequence([AnyElement = #anyType{} |Tail], ElementsSoFar, Acc) -> - {Element, Acc2} = translateElement(AnyElement, Acc), - translateSequence(Tail, [Element | ElementsSoFar], Acc2); + {Element, Acc2} = translateElement(AnyElement, Acc#p1acc{seqCnt = 0}), + translateSequence(Tail, [Element | ElementsSoFar], Acc2#p1acc{seqCnt = Acc#p1acc.seqCnt}); translateSequence([GroupElement = #groupRefType{} |Tail], ElementsSoFar, Acc) -> - {Element, Acc2} = translateElement(GroupElement, Acc), - translateSequence(Tail, [Element | ElementsSoFar], Acc2); + {Element, Acc2} = translateElement(GroupElement, Acc#p1acc{seqCnt = 0}), + translateSequence(Tail, [Element | ElementsSoFar], Acc2#p1acc{seqCnt = Acc#p1acc.seqCnt}); translateSequence([SequenceElement = #sequenceType{} | Tail], ElementsSoFar, Acc) -> - {Element, Acc2} = translateSequenceInSequence(SequenceElement, Acc), - translateSequence(Tail, [Element | ElementsSoFar], Acc2); + {Element, Acc2} = translateSequenceInSequence(SequenceElement, Acc#p1acc{seqCnt = 0}), + translateSequence(Tail, [Element | ElementsSoFar], Acc2#p1acc{seqCnt = Acc#p1acc.seqCnt}); translateSequence(undefined, ElementsSoFar, Acc) -> {lists:reverse(ElementsSoFar), Acc}; diff --git a/test/erlsom_tests.erl b/test/erlsom_tests.erl index b849829..14f8443 100644 --- a/test/erlsom_tests.erl +++ b/test/erlsom_tests.erl @@ -151,3 +151,9 @@ xsi_type_no_prefix_read_test() -> ?assertMatch({'ExtType', _, "base", "ext"}, Parsed). +choice_complex_test() -> + {ok, Xsd} = file:read_file(priv_path(["choice_complex", "choice_complex.xsd"])), + {ok, Xml} = file:read_file(priv_path(["choice_complex", "choice_complex.xml"])), + {ok, Model} = erlsom:compile(Xsd), + {ok, _Data, _} = erlsom:scan(Xml, Model). +