diff --git a/src/SchemaReader.php b/src/SchemaReader.php
index 651c5f9f..6d42222c 100644
--- a/src/SchemaReader.php
+++ b/src/SchemaReader.php
@@ -338,7 +338,7 @@ private static function maybeSetDefault(InterfaceSetDefault $ref, DOMElement $no
}
}
- private function loadSequence(ElementContainer $elementContainer, DOMElement $node, int $max = null): void
+ private function loadSequence(ElementContainer $elementContainer, DOMElement $node, int $max = null, int $min = null): void
{
$max =
(
@@ -348,6 +348,13 @@ private function loadSequence(ElementContainer $elementContainer, DOMElement $no
)
? 2
: null;
+ $min =
+ (
+ $min === null &&
+ !$node->hasAttribute('minOccurs')
+ )
+ ? null
+ : (int) max((int) $min, $node->getAttribute('minOccurs'));
self::againstDOMNodeList(
$node,
@@ -356,13 +363,15 @@ function (
DOMElement $childNode
) use (
$elementContainer,
- $max
+ $max,
+ $min
): void {
$this->loadSequenceChildNode(
$elementContainer,
$node,
$childNode,
- $max
+ $max,
+ $min
);
}
);
@@ -372,7 +381,8 @@ private function loadSequenceChildNode(
ElementContainer $elementContainer,
DOMElement $node,
DOMElement $childNode,
- ? int $max
+ ? int $max,
+ ? int $min = null
): void {
switch ($childNode->localName) {
case 'sequence':
@@ -381,7 +391,8 @@ private function loadSequenceChildNode(
$this->loadSequence(
$elementContainer,
$childNode,
- $max
+ $max,
+ $min
);
break;
case 'element':
@@ -389,7 +400,8 @@ private function loadSequenceChildNode(
$elementContainer,
$node,
$childNode,
- $max
+ $max,
+ $min
);
break;
case 'group':
@@ -407,7 +419,8 @@ private function loadSequenceChildNodeLoadElement(
ElementContainer $elementContainer,
DOMElement $node,
DOMElement $childNode,
- ? int $max
+ ? int $max,
+ ? int $min
): void {
if ($childNode->hasAttribute('ref')) {
$elementDef = $this->findElement($elementContainer->getSchema(), $node, $childNode->getAttribute('ref'));
@@ -436,6 +449,11 @@ private function loadSequenceChildNodeLoadElement(
$childNode
);
}
+
+ if ($min !== null) {
+ $element->setMin($min);
+ }
+
if ($max > 1) {
/*
* although one might think the typecast is not needed with $max being `? int $max` after passing > 1,
diff --git a/tests/TypesTest.php b/tests/TypesTest.php
index 3934fb54..4211de55 100644
--- a/tests/TypesTest.php
+++ b/tests/TypesTest.php
@@ -140,6 +140,66 @@ public function testElementMaxOccurences($xml, $expected)
$this->assertEquals($expected, $elements[0]->getMax());
}
+ /**
+ * @dataProvider getMinOccurencesOverride
+ */
+ public function testSequencMinOccursOverride($xml, $expected)
+ {
+ $schema = $this->reader->readString(
+ '
+
+
+
+
+
+
+ ');
+
+ $complex = $schema->findType('complexType', 'http://www.example.com');
+ $elements = $complex->getElements();
+ $this->assertEquals($expected, $elements[0]->getMin());
+ }
+
+ public function getMinOccurencesOverride()
+ {
+ return [
+ ['2', 2],
+ ['1', 1],
+ ['0', 0],
+ ];
+ }
+
+ /**
+ * @dataProvider getMaxOccurencesOverride
+ */
+ public function testSequencMaxOccursOverride($xml, $expected)
+ {
+ $schema = $this->reader->readString(
+ '
+
+
+
+
+
+
+ ');
+
+ $complex = $schema->findType('complexType', 'http://www.example.com');
+ $elements = $complex->getElements();
+ $this->assertEquals($expected, $elements[0]->getMax());
+ }
+
+ public function getMaxOccurencesOverride()
+ {
+ return [
+ ['0', 5], //maxOccurs=0 is ignored
+ ['1', 5],
+ ['2', 2], // 2 in this case just means "many"
+ ['unbounded', 2], // 2 in this case just means "many"
+ ];
+ }
+
+
public function getMinOccurences()
{
return [