Skip to content

Commit

Permalink
Fix max_occur for dtd choice content types (#760)
Browse files Browse the repository at this point in the history
  • Loading branch information
tefra authored Feb 26, 2023
1 parent f3b4253 commit 9f1778c
Show file tree
Hide file tree
Showing 5 changed files with 22 additions and 10 deletions.
2 changes: 2 additions & 0 deletions tests/codegen/mappers/test_dtd.py
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,7 @@ def test_build_content_type_seq(self):
def test_build_content_type_or(self):
content = DtdContentFactory.create(
type=DtdContentType.OR,
occur=DtdContentOccur.MULT,
left=DtdContentFactory.create(type=DtdContentType.ELEMENT),
right=DtdContentFactory.create(type=DtdContentType.ELEMENT),
)
Expand All @@ -262,6 +263,7 @@ def test_build_content_type_or(self):
for attr in target.attrs:
self.assertEqual(str(id(content)), attr.restrictions.choice)
self.assertEqual(0, attr.restrictions.min_occurs)
self.assertEqual(sys.maxsize, attr.restrictions.max_occurs)

def test_build_content_type_or_nested(self):
content = DtdContentFactory.create(
Expand Down
2 changes: 1 addition & 1 deletion tests/codegen/parsers/test_dtd.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ def test_build_content(self):
"type": DtdContentType.ELEMENT,
},
"name": None,
"occur": DtdContentOccur.ONCE,
"occur": DtdContentOccur.MULT,
"right": {
"left": None,
"name": "Source",
Expand Down
2 changes: 1 addition & 1 deletion tests/fixtures/dtd/complete_example.dtd
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<!ELEMENT Blog (Post+)>
<!ELEMENT Post ((Origin|Source),Title,Body,Tags)>
<!ELEMENT Post ((Origin|Source)*,Title,Body,Tags)>
<!ELEMENT Origin (#PCDATA)>
<!ELEMENT Source (#PCDATA)>
<!ELEMENT Title (#PCDATA)>
Expand Down
8 changes: 4 additions & 4 deletions tests/fixtures/dtd/models/complete_example.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,15 +50,15 @@ class Post:
"required": True,
}
)
origin: Optional[str] = field(
default=None,
origin: List[str] = field(
default_factory=list,
metadata={
"name": "Origin",
"type": "Element",
}
)
source: Optional[str] = field(
default=None,
source: List[str] = field(
default_factory=list,
metadata={
"name": "Source",
"type": "Element",
Expand Down
18 changes: 14 additions & 4 deletions xsdata/codegen/mappers/dtd.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,8 +119,14 @@ def build_content(cls, target: Class, content: DtdContent, **kwargs: Any):
elif content_type == DtdContentType.SEQ:
cls.build_content_tree(target, content, **kwargs)
elif content_type == DtdContentType.OR:
params = {"min_occurs": 0, "choice": str(id(content))}
params.update(kwargs)
params = cls.build_occurs(content.occur)
params.update(
{
"choice": str(id(content)),
"min_occurs": 0,
}
)
params.update(**kwargs)
cls.build_content_tree(target, content, **params)
else: # content_type == DtdContentType.PCDATA:
restrictions = cls.build_restrictions(content.occur, **kwargs)
Expand All @@ -135,7 +141,7 @@ def build_content_tree(cls, target: Class, content: DtdContent, **kwargs: Any):
cls.build_content(target, content.right, **kwargs)

@classmethod
def build_restrictions(cls, occur: DtdContentOccur, **kwargs: Any) -> Restrictions:
def build_occurs(cls, occur: DtdContentOccur) -> Dict:
if occur == DtdContentOccur.ONCE:
min_occurs = 1
max_occurs = 1
Expand All @@ -149,10 +155,14 @@ def build_restrictions(cls, occur: DtdContentOccur, **kwargs: Any) -> Restrictio
min_occurs = 1
max_occurs = sys.maxsize

params: Dict[str, Any] = {
return {
"min_occurs": min_occurs,
"max_occurs": max_occurs,
}

@classmethod
def build_restrictions(cls, occur: DtdContentOccur, **kwargs: Any) -> Restrictions:
params = cls.build_occurs(occur)
params.update(kwargs)

return Restrictions(**params)
Expand Down

0 comments on commit 9f1778c

Please sign in to comment.