diff --git a/.github/workflows/analyzers.yaml b/.github/workflows/analyzers.yaml
index fbdbd31..f8f7ef5 100644
--- a/.github/workflows/analyzers.yaml
+++ b/.github/workflows/analyzers.yaml
@@ -7,7 +7,7 @@ jobs:
strategy:
matrix:
operating-system: [ubuntu-latest]
- php-versions: [ '8.3', '8.4', '8.5' ]
+ php-versions: [ '8.4', '8.5' ]
composer-options: [ '--ignore-platform-req=php+' ]
fail-fast: false
name: PHP ${{ matrix.php-versions }} @ ${{ matrix.operating-system }}
diff --git a/.github/workflows/code-style.yaml b/.github/workflows/code-style.yaml
index fb19bca..a0a18b6 100644
--- a/.github/workflows/code-style.yaml
+++ b/.github/workflows/code-style.yaml
@@ -7,7 +7,7 @@ jobs:
strategy:
matrix:
operating-system: [ubuntu-latest]
- php-versions: [ '8.3', '8.4', '8.5' ]
+ php-versions: [ '8.4', '8.5' ]
composer-options: [ '--ignore-platform-req=php+' ]
fail-fast: false
name: PHP ${{ matrix.php-versions }} @ ${{ matrix.operating-system }}
diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml
index f8cde3d..ec74651 100644
--- a/.github/workflows/tests.yaml
+++ b/.github/workflows/tests.yaml
@@ -7,7 +7,7 @@ jobs:
strategy:
matrix:
operating-system: [ubuntu-latest]
- php-versions: [ '8.3', '8.4', '8.5' ]
+ php-versions: [ '8.4', '8.5' ]
composer-options: [ '--ignore-platform-req=php+' ]
dependency-preference: ['current', 'lowest', 'stable']
fail-fast: false
diff --git a/composer.json b/composer.json
index 954f40c..6f40e36 100644
--- a/composer.json
+++ b/composer.json
@@ -13,14 +13,25 @@
}
},
"require": {
- "php": "~8.3.0 || ~8.4.0 || ~8.5.0",
+ "php": "~8.4.0 || ~8.5.0",
"ext-dom": "*",
"goetas-webservices/xsd-reader": "^0.4.11",
- "php-soap/engine": "^2.19",
- "php-soap/wsdl": "^1.18",
- "php-soap/xml": "^1.9.0",
- "veewee/xml": "^3.6",
- "php-standard-library/php-standard-library": "^3.0 || ^4.0 || ^5.0 || ^6.0",
+ "php-soap/engine": "^2.20",
+ "php-soap/wsdl": "^1.19",
+ "php-soap/xml": "^1.10",
+ "veewee/xml": "^4.10",
+ "php-standard-library/dict": "^6.1",
+ "php-standard-library/foundation": "^6.1",
+ "php-standard-library/fun": "^6.1",
+ "php-standard-library/iter": "^6.1",
+ "php-standard-library/json": "^6.1",
+ "php-standard-library/math": "^6.1",
+ "php-standard-library/option": "^6.1",
+ "php-standard-library/regex": "^6.1",
+ "php-standard-library/result": "^6.1",
+ "php-standard-library/str": "^6.1",
+ "php-standard-library/type": "^6.1",
+ "php-standard-library/vec": "^6.1",
"symfony/console": "^5.4 || ^6.0 || ^7.0 || ^8.0",
"webmozart/assert": "^1.11",
"php-tui/php-tui": "^0.2.1"
diff --git a/psalm.xml b/psalm.xml
index 70f4db3..000ad4f 100644
--- a/psalm.xml
+++ b/psalm.xml
@@ -4,10 +4,14 @@
resolveFromConfigFile="true"
findUnusedCode="false"
ensureOverrideAttribute="false"
+ phpVersion="8.4"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="https://getpsalm.org/schema/config"
xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd"
>
+
+
+
diff --git a/src/Parser/Definitions/AddressBindingTypeParser.php b/src/Parser/Definitions/AddressBindingTypeParser.php
index 9c01b7d..fb51ca9 100644
--- a/src/Parser/Definitions/AddressBindingTypeParser.php
+++ b/src/Parser/Definitions/AddressBindingTypeParser.php
@@ -3,13 +3,13 @@
namespace Soap\WsdlReader\Parser\Definitions;
-use DOMElement;
+use Dom\Element;
use Soap\WsdlReader\Model\Definitions\AddressBindingType;
use VeeWee\Xml\Dom\Document;
final class AddressBindingTypeParser
{
- public function __invoke(Document $wsdl, DOMElement $namespacedElement): AddressBindingType
+ public function __invoke(Document $wsdl, Element $namespacedElement): AddressBindingType
{
return AddressBindingType::from($namespacedElement->namespaceURI ?? '');
}
diff --git a/src/Parser/Definitions/BindingOperationMessageParser.php b/src/Parser/Definitions/BindingOperationMessageParser.php
index 6bc746e..4bf0ec7 100644
--- a/src/Parser/Definitions/BindingOperationMessageParser.php
+++ b/src/Parser/Definitions/BindingOperationMessageParser.php
@@ -3,7 +3,7 @@
namespace Soap\WsdlReader\Parser\Definitions;
-use DOMElement;
+use Dom\Element;
use Psl\Type;
use Soap\WsdlReader\Model\Definitions\BindingOperationMessage;
use Soap\WsdlReader\Model\Definitions\BindingOperationMessages;
@@ -16,7 +16,7 @@
final class BindingOperationMessageParser
{
- public function __invoke(Document $wsdl, DOMElement $message, StrategyInterface $strategy): BindingOperationMessage
+ public function __invoke(Document $wsdl, Element $message, StrategyInterface $strategy): BindingOperationMessage
{
$xpath = $wsdl->xpath(new WsdlPreset($wsdl));
@@ -28,29 +28,29 @@ public function __invoke(Document $wsdl, DOMElement $message, StrategyInterface
public static function tryParseFromOptionalSingleOperationMessage(
Document $wsdl,
- DOMElement $operation,
+ Element $operation,
string $message,
StrategyInterface $strategy
): ?BindingOperationMessage {
$xpath = $wsdl->xpath(new WsdlPreset($wsdl));
return wrap(
- static fn (): DOMElement => assert_element($xpath->querySingle('./wsdl:'.$message, $operation))
+ static fn (): Element => assert_element($xpath->querySingle('./wsdl:'.$message, $operation))
)->proceed(
- static fn (DOMElement $messageElement): BindingOperationMessage =>
+ static fn (Element $messageElement): BindingOperationMessage =>
(new self())($wsdl, $messageElement, $strategy),
static fn () => null
);
}
/**
- * @param NodeList $list
+ * @param NodeList $list
*/
public static function tryParseList(Document $wsdl, NodeList $list, StrategyInterface $strategy): BindingOperationMessages
{
return new BindingOperationMessages(
...$list->map(
- static fn (DOMElement $message): BindingOperationMessage => (new self)($wsdl, $message, $strategy)
+ static fn (Element $message): BindingOperationMessage => (new self)($wsdl, $message, $strategy)
)
);
}
diff --git a/src/Parser/Definitions/BindingOperationParser.php b/src/Parser/Definitions/BindingOperationParser.php
index 2187037..d8b2769 100644
--- a/src/Parser/Definitions/BindingOperationParser.php
+++ b/src/Parser/Definitions/BindingOperationParser.php
@@ -3,28 +3,28 @@
namespace Soap\WsdlReader\Parser\Definitions;
-use DOMElement;
+use Dom\Element;
use Soap\WsdlReader\Model\Definitions\BindingOperation;
use Soap\WsdlReader\Parser\Strategy\StrategyInterface;
use Soap\Xml\Xpath\WsdlPreset;
use VeeWee\Xml\Dom\Document;
-use function VeeWee\Xml\Dom\Locator\Element\locate_by_tag_name;
+use function VeeWee\Xml\Dom\Locator\Element\locate_by_namespaced_tag_name;
final class BindingOperationParser
{
- public function __invoke(Document $wsdl, DOMElement $operation, StrategyInterface $strategy): BindingOperation
+ public function __invoke(Document $wsdl, Element $operation, StrategyInterface $strategy): BindingOperation
{
$xpath = $wsdl->xpath(new WsdlPreset($wsdl));
- $soapOperation = locate_by_tag_name($operation, 'operation')->expectFirst('Unable to locate the operation implementation in a WSDL operation element!');
+ $soapOperation = locate_by_namespaced_tag_name($operation, '*', 'operation')->expectFirst('Unable to locate the operation implementation in a WSDL operation element!');
return new BindingOperation(
- name: $operation->getAttribute('name'),
+ name: $operation->getAttribute('name') ?? '',
implementation: $strategy->parseOperationImplementation($wsdl, $soapOperation),
input: BindingOperationMessageParser::tryParseFromOptionalSingleOperationMessage($wsdl, $operation, 'input', $strategy),
output: BindingOperationMessageParser::tryParseFromOptionalSingleOperationMessage($wsdl, $operation, 'output', $strategy),
fault: BindingOperationMessageParser::tryParseList(
$wsdl,
- $xpath->query('./wsdl:fault', $operation)->expectAllOfType(DOMElement::class),
+ $xpath->query('./wsdl:fault', $operation)->expectAllOfType(Element::class),
$strategy
),
);
diff --git a/src/Parser/Definitions/BindingParser.php b/src/Parser/Definitions/BindingParser.php
index b6e1823..eb610b3 100644
--- a/src/Parser/Definitions/BindingParser.php
+++ b/src/Parser/Definitions/BindingParser.php
@@ -3,7 +3,7 @@
namespace Soap\WsdlReader\Parser\Definitions;
-use DOMElement;
+use Dom\Element;
use Soap\WsdlReader\Model\Definitions\Binding;
use Soap\WsdlReader\Model\Definitions\BindingOperations;
use Soap\WsdlReader\Model\Definitions\Bindings;
@@ -11,28 +11,28 @@
use Soap\WsdlReader\Parser\Strategy\StrategySelector;
use Soap\Xml\Xpath\WsdlPreset;
use VeeWee\Xml\Dom\Document;
-use function VeeWee\Xml\Dom\Locator\Element\locate_by_tag_name;
+use function VeeWee\Xml\Dom\Locator\Element\locate_by_namespaced_tag_name;
final class BindingParser
{
- public function __invoke(Document $wsdl, DOMElement $binding): Binding
+ public function __invoke(Document $wsdl, Element $binding): Binding
{
$xpath = $wsdl->xpath(new WsdlPreset($wsdl));
- $soapBinding = locate_by_tag_name($binding, 'binding')->expectFirst('Unable to locate the SOAP binding in a WSDL binding element!');
+ $soapBinding = locate_by_namespaced_tag_name($binding, '*', 'binding')->expectFirst('Unable to locate the SOAP binding in a WSDL binding element!');
$addressBindingType = (new AddressBindingTypeParser())($wsdl, $soapBinding);
$strategy = (new StrategySelector())($addressBindingType);
return new Binding(
- name: $binding->getAttribute('name'),
- type: QNamed::parse($binding->getAttribute('type')),
+ name: $binding->getAttribute('name') ?? '',
+ type: QNamed::parse($binding->getAttribute('type') ?? ''),
addressBindingType: $addressBindingType,
implementation: $strategy->parseBindingImplementation($wsdl, $soapBinding),
operations: new BindingOperations(
...$xpath->query('./wsdl:operation', $binding)
- ->expectAllOfType(DOMElement::class)
+ ->expectAllOfType(Element::class)
->map(
- static fn (DOMElement $operation) => (new BindingOperationParser())($wsdl, $operation, $strategy)
+ static fn (Element $operation) => (new BindingOperationParser())($wsdl, $operation, $strategy)
)
),
);
@@ -45,9 +45,9 @@ public static function tryParse(Document $wsdl): Bindings
return new Bindings(
...$xpath->query('/wsdl:definitions/wsdl:binding')
- ->expectAllOfType(DOMElement::class)
+ ->expectAllOfType(Element::class)
->map(
- static fn (DOMElement $binding): Binding => $parse($wsdl, $binding)
+ static fn (Element $binding): Binding => $parse($wsdl, $binding)
)
);
}
diff --git a/src/Parser/Definitions/MessageParser.php b/src/Parser/Definitions/MessageParser.php
index 25720e1..fd7a237 100644
--- a/src/Parser/Definitions/MessageParser.php
+++ b/src/Parser/Definitions/MessageParser.php
@@ -3,7 +3,7 @@
namespace Soap\WsdlReader\Parser\Definitions;
-use DOMElement;
+use Dom\Element;
use Soap\WsdlReader\Model\Definitions\Message;
use Soap\WsdlReader\Model\Definitions\Messages;
use Soap\WsdlReader\Model\Definitions\Part;
@@ -14,25 +14,25 @@
final class MessageParser
{
- public function __invoke(Document $wsdl, DOMElement $message): Message
+ public function __invoke(Document $wsdl, Element $message): Message
{
$xpath = $wsdl->xpath(new WsdlPreset($wsdl));
return new Message(
- name: $message->getAttribute('name'),
+ name: $message->getAttribute('name') ?? '',
parts: new Parts(
...$xpath->query('./wsdl:part', $message)
- ->expectAllOfType(DOMElement::class)
+ ->expectAllOfType(Element::class)
->map(
- static function (DOMElement $part) {
+ static function (Element $part) {
$element = match (true) {
- $part->hasAttribute('element') => QNamed::parse($part->getAttribute('element')),
- $part->hasAttribute('type') => QNamed::parse($part->getAttribute('type')),
+ $part->hasAttribute('element') => QNamed::parse($part->getAttribute('element') ?? ''),
+ $part->hasAttribute('type') => QNamed::parse($part->getAttribute('type') ?? ''),
default => null
};
return new Part(
- name: $part->getAttribute('name'),
+ name: $part->getAttribute('name') ?? '',
element: $element,
);
}
@@ -48,9 +48,9 @@ public static function tryParse(Document $wsdl): Messages
return new Messages(
...$xpath->query('/wsdl:definitions/wsdl:message')
- ->expectAllOfType(DOMElement::class)
+ ->expectAllOfType(Element::class)
->map(
- static fn (DOMElement $message) => $parse($wsdl, $message)
+ static fn (Element $message) => $parse($wsdl, $message)
)
);
}
diff --git a/src/Parser/Definitions/NamespacesParser.php b/src/Parser/Definitions/NamespacesParser.php
index 9686f9d..443d2b2 100644
--- a/src/Parser/Definitions/NamespacesParser.php
+++ b/src/Parser/Definitions/NamespacesParser.php
@@ -3,10 +3,11 @@
namespace Soap\WsdlReader\Parser\Definitions;
-use DOMNameSpaceNode;
+use Dom\NamespaceInfo;
use Soap\WsdlReader\Model\Definitions\Namespaces;
use VeeWee\Xml\Dom\Document;
use function Psl\Dict\merge;
+use function Psl\Iter\reduce;
use function VeeWee\Xml\Dom\Locator\document_element;
use function VeeWee\Xml\Dom\Locator\Xmlns\recursive_linked_namespaces;
@@ -18,22 +19,24 @@ public static function tryParse(Document $wsdl): Namespaces
$allNamespaces = recursive_linked_namespaces($root);
return new Namespaces(
- $allNamespaces->reduce(
+ reduce(
+ $allNamespaces,
/**
* @param array $map
* @return array
*/
- static fn (array $map, DOMNameSpaceNode $node): array
- => merge($map, [(string)$node->localName => (string)$node->namespaceURI]),
+ static fn (array $map, NamespaceInfo $node): array
+ => merge($map, [(string)$node->prefix => (string)$node->namespaceURI]),
[]
),
- $allNamespaces->reduce(
+ reduce(
+ $allNamespaces,
/**
* @param array $map
* @return array
*/
- static fn (array $map, DOMNameSpaceNode $node): array
- => merge($map, [(string)$node->namespaceURI => (string)$node->localName]),
+ static fn (array $map, NamespaceInfo $node): array
+ => merge($map, [(string)$node->namespaceURI => (string)$node->prefix]),
[]
)
);
diff --git a/src/Parser/Definitions/OperationParamParser.php b/src/Parser/Definitions/OperationParamParser.php
index d77f3b9..1b5fb24 100644
--- a/src/Parser/Definitions/OperationParamParser.php
+++ b/src/Parser/Definitions/OperationParamParser.php
@@ -3,7 +3,7 @@
namespace Soap\WsdlReader\Parser\Definitions;
-use DOMElement;
+use Dom\Element;
use Psl\Type;
use Soap\WsdlReader\Model\Definitions\Param;
use Soap\WsdlReader\Model\Definitions\Params;
@@ -16,7 +16,7 @@
final class OperationParamParser
{
- public function __invoke(Document $wsdl, DOMElement $operation): Param
+ public function __invoke(Document $wsdl, Element $operation): Param
{
$xpath = $wsdl->xpath(new WsdlPreset($wsdl));
@@ -26,25 +26,25 @@ public function __invoke(Document $wsdl, DOMElement $operation): Param
);
}
- public static function tryParseOptionally(Document $wsdl, string $message, DOMElement $operation): ?Param
+ public static function tryParseOptionally(Document $wsdl, string $message, Element $operation): ?Param
{
$xpath = $wsdl->xpath(new WsdlPreset($wsdl));
- return wrap(static fn (): DOMElement => assert_element($xpath->querySingle('./wsdl:'.$message, $operation)))
+ return wrap(static fn (): Element => assert_element($xpath->querySingle('./wsdl:'.$message, $operation)))
->proceed(
- static fn (DOMElement $messageElement): Param =>
+ static fn (Element $messageElement): Param =>
(new self())($wsdl, $messageElement),
static fn () => null
);
}
/**
- * @param NodeList $params
+ * @param NodeList $params
*/
public static function tryParseList(Document $wsdl, NodeList $params): Params
{
return new Params(
...$params->map(
- static fn (DOMElement $param): Param => (new self)($wsdl, $param)
+ static fn (Element $param): Param => (new self)($wsdl, $param)
)
);
}
diff --git a/src/Parser/Definitions/OperationParser.php b/src/Parser/Definitions/OperationParser.php
index 047cfd1..e6753f5 100644
--- a/src/Parser/Definitions/OperationParser.php
+++ b/src/Parser/Definitions/OperationParser.php
@@ -3,7 +3,7 @@
namespace Soap\WsdlReader\Parser\Definitions;
-use DOMElement;
+use Dom\Element;
use Psl\Type;
use Soap\WsdlReader\Model\Definitions\Operation;
use Soap\Xml\Xpath\WsdlPreset;
@@ -11,7 +11,7 @@
final class OperationParser
{
- public function __invoke(Document $wsdl, DOMElement $operation): Operation
+ public function __invoke(Document $wsdl, Element $operation): Operation
{
$xpath = $wsdl->xpath(new WsdlPreset($wsdl));
@@ -21,7 +21,7 @@ public function __invoke(Document $wsdl, DOMElement $operation): Operation
output: OperationParamParser::tryParseOptionally($wsdl, 'output', $operation),
fault: OperationParamParser::tryParseList(
$wsdl,
- $xpath->query('./wsdl:fault', $operation)->expectAllOfType(DOMElement::class)
+ $xpath->query('./wsdl:fault', $operation)->expectAllOfType(Element::class)
),
documentation: $xpath->evaluate('string(./wsdl:documentation)', Type\string(), $operation),
);
diff --git a/src/Parser/Definitions/PortParser.php b/src/Parser/Definitions/PortParser.php
index 155f2f1..5f3e1cc 100644
--- a/src/Parser/Definitions/PortParser.php
+++ b/src/Parser/Definitions/PortParser.php
@@ -3,22 +3,22 @@
namespace Soap\WsdlReader\Parser\Definitions;
-use DOMElement;
+use Dom\Element;
use Psl\Type;
use Soap\WsdlReader\Model\Definitions\Address;
use Soap\WsdlReader\Model\Definitions\Port;
use Soap\WsdlReader\Model\Definitions\QNamed;
use Soap\Xml\Xpath\WsdlPreset;
use VeeWee\Xml\Dom\Document;
-use function VeeWee\Xml\Dom\Locator\Element\locate_by_tag_name;
+use function VeeWee\Xml\Dom\Locator\Element\locate_by_namespaced_tag_name;
final class PortParser
{
- public function __invoke(Document $wsdl, DOMElement $servicePort): Port
+ public function __invoke(Document $wsdl, Element $servicePort): Port
{
$xpath = $wsdl->xpath(new WsdlPreset($wsdl));
- $address = locate_by_tag_name($servicePort, 'address')->expectFirst('Unable to locate an address section in a service port!');
+ $address = locate_by_namespaced_tag_name($servicePort, '*', 'address')->expectFirst('Unable to locate an address section in a service port!');
$type = (new AddressBindingTypeParser())($wsdl, $address);
return new Port(
diff --git a/src/Parser/Definitions/PortTypeParser.php b/src/Parser/Definitions/PortTypeParser.php
index adb648d..37f5a7f 100644
--- a/src/Parser/Definitions/PortTypeParser.php
+++ b/src/Parser/Definitions/PortTypeParser.php
@@ -3,7 +3,7 @@
namespace Soap\WsdlReader\Parser\Definitions;
-use DOMElement;
+use Dom\Element;
use Soap\WsdlReader\Model\Definitions\Operations;
use Soap\WsdlReader\Model\Definitions\PortType;
use Soap\WsdlReader\Model\Definitions\PortTypes;
@@ -12,17 +12,17 @@
final class PortTypeParser
{
- public function __invoke(Document $wsdl, DOMElement $portType): PortType
+ public function __invoke(Document $wsdl, Element $portType): PortType
{
$xpath = $wsdl->xpath(new WsdlPreset($wsdl));
return new PortType(
- name: $portType->getAttribute('name'),
+ name: $portType->getAttribute('name') ?? '',
operations: new Operations(
...$xpath->query('./wsdl:operation', $portType)
- ->expectAllOfType(DOMElement::class)
+ ->expectAllOfType(Element::class)
->map(
- static fn (DOMElement $operation) => (new OperationParser())($wsdl, $operation)
+ static fn (Element $operation) => (new OperationParser())($wsdl, $operation)
)
),
);
@@ -35,9 +35,9 @@ public static function tryParse(Document $wsdl): PortTypes
return new PortTypes(
...$xpath->query('/wsdl:definitions/wsdl:portType')
- ->expectAllOfType(DOMElement::class)
+ ->expectAllOfType(Element::class)
->map(
- static fn (DOMElement $portType) => $parse($wsdl, $portType)
+ static fn (Element $portType) => $parse($wsdl, $portType)
)
);
}
diff --git a/src/Parser/Definitions/SchemaParser.php b/src/Parser/Definitions/SchemaParser.php
index 3d8c2a6..a571813 100644
--- a/src/Parser/Definitions/SchemaParser.php
+++ b/src/Parser/Definitions/SchemaParser.php
@@ -3,12 +3,17 @@
namespace Soap\WsdlReader\Parser\Definitions;
+use DOMDocument;
+use DOMElement;
+use DOMNode;
+use DOMNodeList;
+use DOMXPath;
use GoetasWebservices\XML\XSDReader\Schema\Schema;
use GoetasWebservices\XML\XSDReader\SchemaReader;
use Soap\WsdlReader\Parser\Context\ParserContext;
use Soap\Xml\Xpath\WsdlPreset;
use VeeWee\Xml\Dom\Document;
-use function VeeWee\Xml\Dom\Locator\document_element;
+use function VeeWee\Xml\ErrorHandling\disallow_libxml_false_returns;
final class SchemaParser
{
@@ -35,13 +40,56 @@ public static function tryParse(Document $wsdl, ParserContext $context): Schema
foreach ($context->knownSchemas as $namespace => $location) {
$reader->addKnownNamespaceSchemaLocation($namespace, 'file://'.$location);
$globalSchema->addSchema(
- $reader->readNode(Document::fromXmlFile($location)->locate(document_element()), $namespace)
+ $reader->readNode(self::legacyDocumentElement($location), $namespace)
);
}
return $reader->readNodes(
- [...$xpath->query('/wsdl:definitions/wsdl:types/schema:schema')],
+ self::legacySchemaNodes($wsdl),
$wsdl->toUnsafeDocument()->documentURI
);
}
+
+ /**
+ * TODO: Can be removed once goetas-webservices/xsd-reader supports Dom\Element.
+ *
+ * @return list
+ */
+ private static function legacySchemaNodes(Document $wsdl): array
+ {
+ $legacyDoc = $wsdl->toUnsafeLegacyDocument();
+ $legacyXpath = new DOMXPath($legacyDoc);
+ $legacyXpath->registerNamespace('wsdl', 'http://schemas.xmlsoap.org/wsdl/');
+ $legacyXpath->registerNamespace('schema', 'http://www.w3.org/2001/XMLSchema');
+
+ /** @var DOMNodeList $nodes */
+ $nodes = disallow_libxml_false_returns(
+ $legacyXpath->query('/wsdl:definitions/wsdl:types/schema:schema'),
+ 'Unable to query schema nodes from legacy document'
+ );
+
+ $result = [];
+ foreach ($nodes as $node) {
+ assert($node instanceof DOMElement);
+ $result[] = $node;
+ }
+
+ return $result;
+ }
+
+ /**
+ * TODO: Can be removed once goetas-webservices/xsd-reader supports Dom\Element.
+ */
+ private static function legacyDocumentElement(string $location): DOMElement
+ {
+ $doc = new DOMDocument();
+ disallow_libxml_false_returns(
+ $doc->load($location),
+ 'Unable to load XML file: '.$location
+ );
+
+ assert($doc->documentElement instanceof DOMElement);
+
+ return $doc->documentElement;
+ }
}
diff --git a/src/Parser/Definitions/ServiceParser.php b/src/Parser/Definitions/ServiceParser.php
index 7641536..4a77a18 100644
--- a/src/Parser/Definitions/ServiceParser.php
+++ b/src/Parser/Definitions/ServiceParser.php
@@ -3,7 +3,7 @@
namespace Soap\WsdlReader\Parser\Definitions;
-use DOMElement;
+use Dom\Element;
use Soap\WsdlReader\Model\Definitions\Port;
use Soap\WsdlReader\Model\Definitions\Ports;
use Soap\WsdlReader\Model\Definitions\Service;
@@ -13,17 +13,17 @@
final class ServiceParser
{
- public function __invoke(Document $wsdl, DOMElement $service): Service
+ public function __invoke(Document $wsdl, Element $service): Service
{
$xpath = $wsdl->xpath(new WsdlPreset($wsdl));
return new Service(
- name: $service->getAttribute('name'),
+ name: $service->getAttribute('name') ?? '',
ports: new Ports(
...$xpath->query('./wsdl:port', $service)
- ->expectAllOfType(DOMElement::class)
+ ->expectAllOfType(Element::class)
->map(
- static fn (DOMElement $servicePort): Port => (new PortParser())($wsdl, $servicePort)
+ static fn (Element $servicePort): Port => (new PortParser())($wsdl, $servicePort)
)
)
);
@@ -36,9 +36,9 @@ public static function tryParse(Document $wsdl): Services
return new Services(
...$xpath->query('/wsdl:definitions/wsdl:service')
- ->expectAllOfType(DOMElement::class)
+ ->expectAllOfType(Element::class)
->map(
- static fn (DOMElement $service) => $parse($wsdl, $service)
+ static fn (Element $service) => $parse($wsdl, $service)
)
);
}
diff --git a/src/Parser/Definitions/SoapVersionParser.php b/src/Parser/Definitions/SoapVersionParser.php
index 853db53..2f80b92 100644
--- a/src/Parser/Definitions/SoapVersionParser.php
+++ b/src/Parser/Definitions/SoapVersionParser.php
@@ -3,14 +3,14 @@
namespace Soap\WsdlReader\Parser\Definitions;
-use DOMElement;
+use Dom\Element;
use Soap\WsdlReader\Model\Definitions\SoapVersion;
use Soap\Xml\Xmlns;
use VeeWee\Xml\Dom\Document;
final class SoapVersionParser
{
- public function __invoke(Document $wsdl, DOMElement $soapNamespacedElement): SoapVersion
+ public function __invoke(Document $wsdl, Element $soapNamespacedElement): SoapVersion
{
return match ($soapNamespacedElement->namespaceURI ?? '') {
Xmlns::soap()->value() => SoapVersion::SOAP_11,
diff --git a/src/Parser/Definitions/TargetNamespaceParser.php b/src/Parser/Definitions/TargetNamespaceParser.php
index 74b90a9..cb2a3ff 100644
--- a/src/Parser/Definitions/TargetNamespaceParser.php
+++ b/src/Parser/Definitions/TargetNamespaceParser.php
@@ -12,8 +12,10 @@ public static function tryParse(Document $wsdl): ?Xmlns
{
$definitions = $wsdl->locateDocumentElement();
- return $definitions->hasAttribute('targetNamespace')
- ? Xmlns::load($definitions->getAttribute('targetNamespace'))
+ $targetNamespace = $definitions->getAttribute('targetNamespace');
+
+ return $targetNamespace !== null
+ ? Xmlns::load($targetNamespace)
: null;
}
}
diff --git a/src/Parser/Strategy/HttpStrategy.php b/src/Parser/Strategy/HttpStrategy.php
index b6c7f1b..db47b7d 100644
--- a/src/Parser/Strategy/HttpStrategy.php
+++ b/src/Parser/Strategy/HttpStrategy.php
@@ -3,7 +3,7 @@
namespace Soap\WsdlReader\Parser\Strategy;
-use DOMElement;
+use Dom\Element;
use Soap\WsdlReader\Model\Definitions\Implementation\Binding\BindingImplementation;
use Soap\WsdlReader\Model\Definitions\Implementation\Binding\HttpBinding;
use Soap\WsdlReader\Model\Definitions\Implementation\Message\HttpMessage;
@@ -19,22 +19,22 @@ final class HttpStrategy implements StrategyInterface
private const HTTP_NAMESPACE = 'http://schemas.xmlsoap.org/wsdl/http/';
private const MIME_NAMESPACE = 'http://schemas.xmlsoap.org/wsdl/mime/';
- public function parseBindingImplementation(Document $wsdl, DOMElement $binding): BindingImplementation
+ public function parseBindingImplementation(Document $wsdl, Element $binding): BindingImplementation
{
return new HttpBinding(
- verb: $binding->getAttribute('verb'),
+ verb: $binding->getAttribute('verb') ?? '',
transport: TransportType::tryFrom((string) $binding->namespaceURI) ?? TransportType::HTTP,
);
}
- public function parseOperationImplementation(Document $wsdl, DOMElement $operation): OperationImplementation
+ public function parseOperationImplementation(Document $wsdl, Element $operation): OperationImplementation
{
return new HttpOperation(
- location: $operation->getAttribute('location'),
+ location: $operation->getAttribute('location') ?? '',
);
}
- public function parseMessageImplementation(Document $wsdl, DOMElement $message): MessageImplementation
+ public function parseMessageImplementation(Document $wsdl, Element $message): MessageImplementation
{
$info = children($message)->first();
$fallbackImplementation = new HttpMessage(
@@ -53,7 +53,7 @@ public function parseMessageImplementation(Document $wsdl, DOMElement $message):
),
self::MIME_NAMESPACE => new HttpMessage(
contentType: match($info->localName) {
- 'content' => $info->hasAttribute('type') ? $info->getAttribute('type'): 'application/xml',
+ 'content' => $info->getAttribute('type') ?? 'application/xml',
'mimeXml' => 'application/xml',
'multipartRelated' => 'Multipart/Related',
default => 'application/xml'
diff --git a/src/Parser/Strategy/SoapStrategy.php b/src/Parser/Strategy/SoapStrategy.php
index 0ada2da..9324415 100644
--- a/src/Parser/Strategy/SoapStrategy.php
+++ b/src/Parser/Strategy/SoapStrategy.php
@@ -3,7 +3,7 @@
namespace Soap\WsdlReader\Parser\Strategy;
-use DOMElement;
+use Dom\Element;
use Soap\WsdlReader\Model\Definitions\BindingStyle;
use Soap\WsdlReader\Model\Definitions\BindingUse;
use Soap\WsdlReader\Model\Definitions\EncodingStyle;
@@ -18,31 +18,31 @@
use Soap\WsdlReader\Parser\Definitions\SoapVersionParser;
use VeeWee\Xml\Dom\Document;
use VeeWee\Xml\Xmlns\Xmlns;
-use function VeeWee\Xml\Dom\Locator\Element\locate_by_tag_name;
+use function VeeWee\Xml\Dom\Locator\Element\locate_by_namespaced_tag_name;
final class SoapStrategy implements StrategyInterface
{
- public function parseBindingImplementation(Document $wsdl, DOMElement $binding): BindingImplementation
+ public function parseBindingImplementation(Document $wsdl, Element $binding): BindingImplementation
{
return new SoapBinding(
version: $this->parseVersionFromNode($wsdl, $binding),
- transport: TransportType::from($binding->getAttribute('transport')),
- style: BindingStyle::tryFromCaseInsensitive($binding->getAttribute('style')),
+ transport: TransportType::from($binding->getAttribute('transport') ?? ''),
+ style: BindingStyle::tryFromCaseInsensitive($binding->getAttribute('style') ?? ''),
);
}
- public function parseOperationImplementation(Document $wsdl, DOMElement $operation): OperationImplementation
+ public function parseOperationImplementation(Document $wsdl, Element $operation): OperationImplementation
{
return new SoapOperation(
version: $this->parseVersionFromNode($wsdl, $operation),
- action: $operation->getAttribute('soapAction'),
- style: BindingStyle::tryFromCaseInsensitive($operation->getAttribute('style')),
+ action: $operation->getAttribute('soapAction') ?? '',
+ style: BindingStyle::tryFromCaseInsensitive($operation->getAttribute('style') ?? ''),
);
}
- public function parseMessageImplementation(Document $wsdl, DOMElement $message): MessageImplementation
+ public function parseMessageImplementation(Document $wsdl, Element $message): MessageImplementation
{
- $body = locate_by_tag_name($message, 'body')->item(0);
+ $body = locate_by_namespaced_tag_name($message, '*', 'body')->item(0);
if (!$body) {
return new SoapMessage(
bindingUse: BindingUse::LITERAL,
@@ -51,14 +51,16 @@ public function parseMessageImplementation(Document $wsdl, DOMElement $message):
);
}
+ $namespace = $body->getAttribute('namespace');
+
return new SoapMessage(
- bindingUse: BindingUse::tryFromCaseInsensitive($body->getAttribute('use')) ?? BindingUse::LITERAL,
- namespace: $body->hasAttribute('namespace') ? Xmlns::load($body->getAttribute('namespace')) : null,
- encodingStyle: EncodingStyle::tryFrom($body->getAttribute('encodingStyle')),
+ bindingUse: BindingUse::tryFromCaseInsensitive($body->getAttribute('use') ?? '') ?? BindingUse::LITERAL,
+ namespace: $namespace !== null ? Xmlns::load($namespace) : null,
+ encodingStyle: EncodingStyle::tryFrom($body->getAttribute('encodingStyle') ?? ''),
);
}
- private function parseVersionFromNode(Document $wsdl, DOMElement $element): SoapVersion
+ private function parseVersionFromNode(Document $wsdl, Element $element): SoapVersion
{
return (new SoapVersionParser())($wsdl, $element);
}
diff --git a/src/Parser/Strategy/StrategyInterface.php b/src/Parser/Strategy/StrategyInterface.php
index c092dfa..e607959 100644
--- a/src/Parser/Strategy/StrategyInterface.php
+++ b/src/Parser/Strategy/StrategyInterface.php
@@ -3,7 +3,7 @@
namespace Soap\WsdlReader\Parser\Strategy;
-use DOMElement;
+use Dom\Element;
use Soap\WsdlReader\Model\Definitions\Implementation\Binding\BindingImplementation;
use Soap\WsdlReader\Model\Definitions\Implementation\Message\MessageImplementation;
use Soap\WsdlReader\Model\Definitions\Implementation\Operation\OperationImplementation;
@@ -11,7 +11,7 @@
interface StrategyInterface
{
- public function parseBindingImplementation(Document $wsdl, DOMElement $binding): BindingImplementation;
- public function parseOperationImplementation(Document $wsdl, DOMElement $operation): OperationImplementation;
- public function parseMessageImplementation(Document $wsdl, DOMElement $message): MessageImplementation;
+ public function parseBindingImplementation(Document $wsdl, Element $binding): BindingImplementation;
+ public function parseOperationImplementation(Document $wsdl, Element $operation): OperationImplementation;
+ public function parseMessageImplementation(Document $wsdl, Element $message): MessageImplementation;
}
diff --git a/tests/PhpCompatibility/schema004.phpt b/tests/PhpCompatibility/schema004.phpt
index d116be9..a35374e 100644
--- a/tests/PhpCompatibility/schema004.phpt
+++ b/tests/PhpCompatibility/schema004.phpt
@@ -13,4 +13,4 @@ EOF;
test_schema($schema,'type="tns:testType"');
?>
--EXPECT--
-FATAL (GoetasWebservices\XML\XSDReader\Exception\TypeException):Can't find type named {http://test-uri/}#testType2, at line 13 in some.wsdl
+FATAL (GoetasWebservices\XML\XSDReader\Exception\TypeException):Can't find type named {http://test-uri/}#testType2, at line 6 in some.wsdl