Skip to content
This repository was archived by the owner on Jun 28, 2025. It is now read-only.

Commit c2d32f4

Browse files
committed
add xs:sequence element
1 parent e3b4c59 commit c2d32f4

File tree

3 files changed

+218
-0
lines changed

3 files changed

+218
-0
lines changed

src/XML/xsd/Sequence.php

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace SimpleSAML\XSD\XML\xsd;
6+
7+
use DOMElement;
8+
use SimpleSAML\Assert\Assert;
9+
use SimpleSAML\XML\Exception\{InvalidDOMElementException, SchemaViolationException, TooManyElementsException};
10+
use SimpleSAML\XML\{SchemaValidatableElementInterface, SchemaValidatableElementTrait};
11+
use SimpleSAML\XML\Type\{IDValue, NCNameValue, QNameValue};
12+
13+
use function array_merge;
14+
use function array_pop;
15+
16+
/**
17+
* Class representing the sequence-element.
18+
*
19+
* @package simplesamlphp/xml-xsd
20+
*/
21+
final class Sequence extends AbstractExplicitGroup implements
22+
NestedParticleInterface,
23+
ParticleInterface,
24+
SchemaValidatableElementInterface
25+
{
26+
use SchemaValidatableElementTrait;
27+
28+
/** @var string */
29+
public const LOCALNAME = 'sequence';
30+
31+
32+
/**
33+
* Create an instance of this object from its XML representation.
34+
*
35+
* @param \DOMElement $xml
36+
* @return static
37+
*
38+
* @throws \SimpleSAML\XML\Exception\InvalidDOMElementException
39+
* if the qualified name of the supplied element is wrong
40+
*/
41+
public static function fromXML(DOMElement $xml): static
42+
{
43+
Assert::same($xml->localName, static::getLocalName(), InvalidDOMElementException::class);
44+
Assert::same($xml->namespaceURI, static::NS, InvalidDOMElementException::class);
45+
46+
// Prohibited attributes
47+
$name = self::getOptionalAttribute($xml, 'name', NCNameValue::class, null);
48+
Assert::null($name, SchemaViolationException::class);
49+
50+
$ref = self::getOptionalAttribute($xml, 'ref', QNameValue::class, null);
51+
Assert::null($ref, SchemaViolationException::class);
52+
53+
$annotation = Annotation::getChildrenOfClass($xml);
54+
Assert::maxCount($annotation, 1, TooManyElementsException::class);
55+
56+
$all = All::getChildrenOfClass($xml);
57+
$choice = Choice::getChildrenOfClass($xml);
58+
$element = Element::getChildrenOfClass($xml);
59+
$referencedGroup = ReferencedGroup::getChildrenOfClass($xml);
60+
$sequence = Sequence::getChildrenOfClass($xml);
61+
62+
$particles = array_merge($all, $choice, $element, $referencedGroup, $sequence);
63+
64+
return new static(
65+
nestedParticles: $particles,
66+
annotation: array_pop($annotation),
67+
id: self::getOptionalAttribute($xml, 'id', IDValue::class, null),
68+
namespacedAttributes: self::getAttributesNSFromXML($xml),
69+
);
70+
}
71+
}

tests/XML/xsd/SequenceTest.php

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace SimpleSAML\XSD\Test\XML\xsd;
6+
7+
use DOMText;
8+
use PHPUnit\Framework\Attributes\{CoversClass, Group};
9+
use PHPUnit\Framework\TestCase;
10+
use SimpleSAML\XML\Attribute as XMLAttribute;
11+
use SimpleSAML\XML\Constants as C;
12+
use SimpleSAML\XML\DOMDocumentFactory;
13+
use SimpleSAML\XML\TestUtils\SerializableElementTestTrait;
14+
use SimpleSAML\XML\Type\{AnyURIValue, IDValue, NCNameValue, StringValue, QNameValue};
15+
use SimpleSAML\XSD\Type\{MinOccursValue, MaxOccursValue, NamespaceListValue, ProcessContentsValue};
16+
use SimpleSAML\XSD\XML\xsd\AbstractAnnotated;
17+
use SimpleSAML\XSD\XML\xsd\AbstractGroup;
18+
use SimpleSAML\XSD\XML\xsd\AbstractRealGroup;
19+
use SimpleSAML\XSD\XML\xsd\AbstractOpenAttrs;
20+
use SimpleSAML\XSD\XML\xsd\AbstractXsdElement;
21+
use SimpleSAML\XSD\XML\xsd\Annotation;
22+
use SimpleSAML\XSD\XML\xsd\Appinfo;
23+
use SimpleSAML\XSD\XML\xsd\Sequence;
24+
use SimpleSAML\XSD\XML\xsd\Documentation;
25+
use SimpleSAML\XSD\XML\xsd\ReferencedGroup;
26+
27+
use function dirname;
28+
use function strval;
29+
30+
/**
31+
* Tests for xs:sequence
32+
*
33+
* @package simplesamlphp/xml-xsd
34+
*/
35+
#[Group('xs')]
36+
#[CoversClass(Sequence::class)]
37+
#[CoversClass(AbstractRealGroup::class)]
38+
#[CoversClass(AbstractGroup::class)]
39+
#[CoversClass(AbstractAnnotated::class)]
40+
#[CoversClass(AbstractOpenAttrs::class)]
41+
#[CoversClass(AbstractXsdElement::class)]
42+
final class SequenceTest extends TestCase
43+
{
44+
use SerializableElementTestTrait;
45+
46+
47+
/**
48+
*/
49+
public static function setUpBeforeClass(): void
50+
{
51+
self::$testedClass = SequenceGroup::class;
52+
53+
self::$xmlRepresentation = DOMDocumentFactory::fromFile(
54+
dirname(__FILE__, 3) . '/resources/xml/sequence.xml',
55+
);
56+
}
57+
58+
59+
// test marshalling
60+
61+
62+
/**
63+
* Test creating an Sequence object from scratch.
64+
*/
65+
public function testMarshalling(): void
66+
{
67+
$appinfoDocument = DOMDocumentFactory::create();
68+
$text = new DOMText('Application Information');
69+
$appinfoDocument->appendChild($text);
70+
71+
$otherAppinfoDocument = DOMDocumentFactory::create();
72+
$otherText = new DOMText('Other Application Information');
73+
$otherAppinfoDocument->appendChild($otherText);
74+
75+
$documentationDocument = DOMDocumentFactory::create();
76+
$text = new DOMText('Some Documentation');
77+
$documentationDocument->appendChild($text);
78+
79+
$otherDocumentationDocument = DOMDocumentFactory::create();
80+
$text = new DOMText('Other Documentation');
81+
$otherDocumentationDocument->appendChild($text);
82+
83+
$attr1 = new XMLAttribute('urn:x-simplesamlphp:namespace', 'ssp', 'attr1', StringValue::fromString('value1'));
84+
$attr2 = new XMLAttribute('urn:x-simplesamlphp:namespace', 'ssp', 'attr2', StringValue::fromString('value2'));
85+
$attr3 = new XMLAttribute('urn:x-simplesamlphp:namespace', 'ssp', 'attr3', StringValue::fromString('value3'));
86+
$attr4 = new XMLAttribute('urn:x-simplesamlphp:namespace', 'ssp', 'attr4', StringValue::fromString('value4'));
87+
$langattr = new XMLAttribute(C::NS_XML, 'xml', 'lang', StringValue::fromString('nl'));
88+
89+
$appinfo1 = new Appinfo(
90+
$appinfoDocument->childNodes,
91+
AnyURIValue::fromString('urn:x-simplesamlphp:source'),
92+
[$attr1],
93+
);
94+
$appinfo2 = new Appinfo(
95+
$otherAppinfoDocument->childNodes,
96+
AnyURIValue::fromString('urn:x-simplesamlphp:source'),
97+
[$attr2],
98+
);
99+
100+
$documentation1 = new Documentation(
101+
$documentationDocument->childNodes,
102+
$langattr,
103+
AnyURIValue::fromString('urn:x-simplesamlphp:source'),
104+
[$attr1],
105+
);
106+
$documentation2 = new Documentation(
107+
$otherDocumentationDocument->childNodes,
108+
$langattr,
109+
AnyURIValue::fromString('urn:x-simplesamlphp:source'),
110+
[$attr2],
111+
);
112+
113+
$annotation = new Annotation(
114+
[$appinfo1, $appinfo2],
115+
[$documentation1, $documentation2],
116+
IDValue::fromString('phpunit_annotation'),
117+
[$attr3],
118+
);
119+
120+
$referencedGroup = new ReferencedGroup(
121+
QNameValue::fromString("{http://www.w3.org/2001/XMLSchema}xsd:nestedParticle"),
122+
);
123+
124+
$sequence = new Sequence(
125+
MinOccursValue::fromInteger(0),
126+
MaxOccursValue::fromString('unbounded'),
127+
[$referencedGroup],
128+
$annotation,
129+
IDValue::fromString('phpunit_sequence'),
130+
[$attr4],
131+
);
132+
133+
$this->assertEquals(
134+
self::$xmlRepresentation->saveXML(self::$xmlRepresentation->documentElement),
135+
strval($sequence),
136+
);
137+
}
138+
}

tests/resources/xml/sequence.xml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<xsd:sequence xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:ssp="urn:x-simplesamlphp:namespace" ssp:attr4="value4" id="phpunit_sequence" minOccurs="0" maxOccurs="unbounded">
2+
<xsd:annotation ssp:attr3="value3" id="phpunit_annotation">
3+
<xsd:appinfo source="urn:x-simplesamlphp:source" ssp:attr1="value1">Application Information</xsd:appinfo>
4+
<xsd:appinfo source="urn:x-simplesamlphp:source" ssp:attr2="value2">Other Application Information</xsd:appinfo>
5+
<xsd:documentation xmlns:xml="http://www.w3.org/XML/1998/namespace" source="urn:x-simplesamlphp:source" xml:lang="nl" ssp:attr1="value1">Some Documentation</xsd:documentation>
6+
<xsd:documentation xmlns:xml="http://www.w3.org/XML/1998/namespace" source="urn:x-simplesamlphp:source" xml:lang="nl" ssp:attr2="value2">Other Documentation</xsd:documentation>
7+
</xsd:annotation>
8+
<xsd:group ref="xsd:nestedParticle"/>
9+
</xsd:sequence>

0 commit comments

Comments
 (0)