Parser::parseNamespaces()   A
last analyzed

Complexity

Conditions 4
Paths 3

Size

Total Lines 13
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 4

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 6
c 1
b 0
f 0
dl 0
loc 13
ccs 7
cts 7
cp 1
rs 10
cc 4
nc 3
nop 1
crap 4
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Inspirum\XML\Parser;
6
7
use InvalidArgumentException;
8
use function count;
9
use function explode;
10
use function preg_match;
11
use function sprintf;
12
13
/**
14
 * @internal
15
 */
16
final class Parser
17
{
18
    /**
19
     * Parse node name to namespace prefix and local name
20
     *
21
     * @return array{0: string|null, 1: string}
22
     */
23 86
    public static function parseQualifiedName(string $name): array
24
    {
25 86
        self::validateElementName($name);
26
27 83
        if ($name === 'xmlns') {
28 15
            return [$name, ''];
29
        }
30
31 83
        $parsed = explode(':', $name, 2);
32
33 83
        if (count($parsed) === 2) {
34 35
            return $parsed;
35
        }
36
37 74
        return [null, $parsed[0]];
38
    }
39
40
    /**
41
     * Get local name from node name
42
     */
43 8
    public static function getLocalName(string $name): string
44
    {
45 8
        return self::parseQualifiedName($name)[1];
46
    }
47
48
    /**
49
     * Get namespace prefix from node name
50
     */
51 80
    public static function getNamespacePrefix(string $name): ?string
52
    {
53 80
        return self::parseQualifiedName($name)[0];
54
    }
55
56
    /**
57
     * Validate element name
58
     *
59
     * @throws \InvalidArgumentException
60
     */
61 86
    private static function validateElementName(string $value): void
62
    {
63 86
        $regex = '/^([a-zA-Z_][\w.-]*)(:[a-zA-Z_][\w.-]*)?$/';
64
65 86
        if (preg_match($regex, $value) !== 1) {
66 6
            throw new InvalidArgumentException(
67 6
                sprintf('Element name or namespace prefix [%s] has invalid value', $value),
68 6
            );
69
        }
70
    }
71
72
    /**
73
     * Prefix namespaces with xmlns
74
     *
75
     * @param array<string,string> $attributes
76
     *
77
     * @return array<string,string>
78
     */
79 37
    public static function parseNamespaces(array $attributes): array
80
    {
81 37
        $namespaces = [];
82
83 37
        foreach ($attributes as $attributeName => $attributeValue) {
84 36
            [$prefix, $namespaceLocalName] = self::parseQualifiedName($attributeName);
85
86 36
            if ($prefix === 'xmlns' && $attributeValue !== '') {
87 17
                $namespaces[$namespaceLocalName] = $attributeValue;
88
            }
89
        }
90
91 37
        return $namespaces;
92
    }
93
}
94