Skip to content

Commit 5d8e020

Browse files
authored
Merge pull request #38 from veewee/ComplexTypeSimpleContent-nillable-decoding-logic
Improve parsing of ComplexTypeSimpleContent according to XSD rules.
2 parents 5bd6663 + 94ad884 commit 5d8e020

File tree

3 files changed

+105
-5
lines changed

3 files changed

+105
-5
lines changed

src/Xml/Reader/DocumentToLookupArrayReader.php

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,12 @@
77
use DOMNode;
88
use Soap\Encoding\Xml\Node\Element;
99
use Soap\Encoding\Xml\Node\ElementList;
10+
use VeeWee\Xml\Xmlns\Xmlns;
1011
use function VeeWee\Xml\Dom\Predicate\is_element;
1112

1213
/**
13-
* @psalm-type LookupArray = array<string, string|Element|ElementList>
14+
* @psalm-type LookupArrayValue = string|Element|ElementList
15+
* @psalm-type LookupArray = array<string, LookupArrayValue>
1416
*/
1517
final class DocumentToLookupArrayReader
1618
{
@@ -20,7 +22,7 @@ final class DocumentToLookupArrayReader
2022
public function __invoke(Element $xml): array
2123
{
2224
$root = $xml->element();
23-
/** @var array<string, string|Element|ElementList> $nodes */
25+
/** @var LookupArray $nodes */
2426
$nodes = [];
2527

2628
// Read all child elements.
@@ -38,7 +40,7 @@ public function __invoke(Element $xml): array
3840
$currentElement = Element::fromDOMElement($element);
3941

4042
// Incrementally build up lists.
41-
/** @var string|Element|ElementList $value */
43+
/** @var LookupArrayValue $value */
4244
$value = match(true) {
4345
$previousValue instanceof ElementList => $previousValue->append($currentElement),
4446
$previousValue instanceof Element => new ElementList($previousValue, $currentElement),
@@ -50,8 +52,8 @@ public function __invoke(Element $xml): array
5052

5153
// It might be possible that the child is a regular textNode.
5254
// In that case, we use '_' as the key and the value of the textNode as value.
53-
if (!$nodes && $content = trim($root->textContent)) {
54-
$nodes['_'] = $content;
55+
if (!$nodes && $root->getAttributeNS(Xmlns::xsi()->value(), 'nil') !== 'true') {
56+
$nodes['_'] = $root->textContent;
5557
}
5658

5759
// All attributes also need to be added as key => value pairs.
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
<?php
2+
declare(strict_types=1);
3+
4+
namespace Soap\Encoding\Test\PhpCompatibility;
5+
6+
use PHPUnit\Framework\Attributes\CoversClass;
7+
use Soap\Encoding\Decoder;
8+
use Soap\Encoding\Driver;
9+
use Soap\Encoding\Encoder;
10+
11+
#[CoversClass(Driver::class)]
12+
#[CoversClass(Encoder::class)]
13+
#[CoversClass(Decoder::class)]
14+
final class Schema062Variant1Test extends AbstractCompatibilityTests
15+
{
16+
protected string $schema = <<<EOXML
17+
<complexType name="testType">
18+
<simpleContent>
19+
<restriction base="string">
20+
<attribute name="int" type="int"/>
21+
</restriction>
22+
</simpleContent>
23+
</complexType>
24+
EOXML;
25+
protected string $type = 'type="testType"';
26+
27+
protected function calculateParam(): mixed
28+
{
29+
return (object)[
30+
'_' => '',
31+
'int' => 123
32+
];
33+
}
34+
35+
protected function expectXml(): string
36+
{
37+
return <<<XML
38+
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tns="http://test-uri/"
39+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
40+
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/">
41+
<SOAP-ENV:Body SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
42+
<tns:test>
43+
<testParam int="123" xsi:type="tns:testType"/>
44+
</tns:test>
45+
</SOAP-ENV:Body>
46+
</SOAP-ENV:Envelope>
47+
XML;
48+
}
49+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
<?php
2+
declare(strict_types=1);
3+
4+
namespace Soap\Encoding\Test\PhpCompatibility;
5+
6+
use PHPUnit\Framework\Attributes\CoversClass;
7+
use Soap\Encoding\Decoder;
8+
use Soap\Encoding\Driver;
9+
use Soap\Encoding\Encoder;
10+
11+
#[CoversClass(Driver::class)]
12+
#[CoversClass(Encoder::class)]
13+
#[CoversClass(Decoder::class)]
14+
final class Schema062Variant2Test extends AbstractCompatibilityTests
15+
{
16+
protected string $schema = <<<EOXML
17+
<complexType name="testType">
18+
<simpleContent>
19+
<restriction base="string">
20+
<attribute name="int" type="int"/>
21+
</restriction>
22+
</simpleContent>
23+
</complexType>
24+
EOXML;
25+
protected string $type = 'type="testType"';
26+
27+
protected function calculateParam(): mixed
28+
{
29+
return (object)[
30+
'_' => null,
31+
'int' => 123
32+
];
33+
}
34+
35+
protected function expectXml(): string
36+
{
37+
return <<<XML
38+
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tns="http://test-uri/"
39+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
40+
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/">
41+
<SOAP-ENV:Body SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
42+
<tns:test>
43+
<testParam xsi:nil="true" int="123" xsi:type="tns:testType"/>
44+
</tns:test>
45+
</SOAP-ENV:Body>
46+
</SOAP-ENV:Envelope>
47+
XML;
48+
}
49+
}

0 commit comments

Comments
 (0)