• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

BenMorel / XMLStreamer / 19268377712

11 Nov 2025 02:14PM UTC coverage: 91.935%. Remained the same
19268377712

push

github

BenMorel
Require PHP 8.1

57 of 62 relevant lines covered (91.94%)

15.98 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

87.88
/src/XMLReader.php
1
<?php
2

3
declare(strict_types=1);
4

5
namespace BenMorel\XMLStreamer;
6

7
/**
8
 * Wrapper for the native XMLReader, that throws exceptions instead of triggering PHP errors.
9
 */
10
final class XMLReader
11
{
12
    /**
13
     * The wrapped native XMLReader instance.
14
     */
15
    private \XMLReader $xmlReader;
16

17
    /**
18
     * The transient error handler used to catch PHP errors triggered in the native XMLReader class.
19
     *
20
     * @var \Closure(int, string): never
21
     */
22
    private \Closure $errorHandler;
23

24
    /**
25
     * XMLReader constructor.
26
     */
27
    public function __construct()
28
    {
29
        $this->xmlReader = new \XMLReader();
26✔
30

31
        $this->errorHandler = static function(int $severity, string $message) : void {
26✔
32
            throw new XMLReaderException($message);
8✔
33
        };
26✔
34
    }
35

36
    /**
37
     * Returns the depth of the node in the tree, starting at zero.
38
     */
39
    public function depth() : int
40
    {
41
        return $this->xmlReader->depth;
21✔
42
    }
43

44
    /**
45
     * Returns the qualified name of the current node.
46
     *
47
     * Returns an empty string if the current node does not have a name.
48
     */
49
    public function name() : string
50
    {
51
        return $this->xmlReader->name;
21✔
52
    }
53

54
    /**
55
     * Returns the type of the current node, as an XMLReader::* constant.
56
     */
57
    public function nodeType() : int
58
    {
59
        return $this->xmlReader->nodeType;
25✔
60
    }
61

62
    /**
63
     * Opens a URI containing an XML document to parse.
64
     *
65
     * @param string      $uri      URI pointing to the document.
66
     * @param string|null $encoding The document encoding or NULL.
67
     * @param int         $options  A bitmask of the LIBXML_* constants.
68
     *
69
     * @throws XMLReaderException
70
     */
71
    public function open(string $uri, ?string $encoding = null, int $options = 0) : void
72
    {
73
        set_error_handler($this->errorHandler);
26✔
74

75
        try {
76
            $result = $this->xmlReader->open($uri, $encoding, $options);
26✔
77
        } finally {
78
            restore_error_handler();
26✔
79
        }
80

81
        if ($result !== true) {
25✔
82
            throw XMLReaderException::unknownError(__FUNCTION__);
×
83
        }
84
    }
85

86
    /**
87
     * Closes the input the XMLReader object is currently parsing.
88
     *
89
     * @throws XMLReaderException
90
     */
91
    public function close() : void
92
    {
93
        set_error_handler($this->errorHandler);
18✔
94

95
        try {
96
            $result = $this->xmlReader->close();
18✔
97
        } finally {
98
            restore_error_handler();
18✔
99
        }
100

101
        if ($result !== true) {
18✔
102
            throw XMLReaderException::unknownError(__FUNCTION__);
×
103
        }
104
    }
105

106
    /**
107
     * Returns a copy of the current node as a DOM object.
108
     *
109
     * @throws XMLReaderException
110
     */
111
    public function expand(?\DOMNode $baseNode = null) : \DOMNode
112
    {
113
        set_error_handler($this->errorHandler);
11✔
114

115
        try {
116
            $result = $this->xmlReader->expand($baseNode);
11✔
117
        } finally {
118
            restore_error_handler();
11✔
119
        }
120

121
        if ($result === false) {
11✔
122
            throw XMLReaderException::unknownError(__FUNCTION__);
×
123
        }
124

125
        return $result;
11✔
126
    }
127

128
    /**
129
     * Moves the cursor to the next node in the document.
130
     *
131
     * @return bool True if successful, false is there are no more nodes.
132
     *
133
     * @throws XMLReaderException
134
     */
135
    public function read() : bool
136
    {
137
        set_error_handler($this->errorHandler);
25✔
138

139
        try {
140
            $result = $this->xmlReader->read();
25✔
141
        } finally {
142
            restore_error_handler();
25✔
143
        }
144

145
        return $result;
21✔
146
    }
147

148
    /**
149
     * Moves the cursor to the next node in the document, skipping all subtrees.
150
     *
151
     * @return bool True if successful, false is there are no more nodes.
152
     *
153
     * @throws XMLReaderException
154
     */
155
    public function next(?string $localName = null) : bool
156
    {
157
        set_error_handler($this->errorHandler);
20✔
158

159
        try {
160
            if ($localName !== null) {
20✔
161
                $result = $this->xmlReader->next($localName);
×
162
            } else {
163
                $result = $this->xmlReader->next();
20✔
164
            }
165
        } finally {
166
            restore_error_handler();
20✔
167
        }
168

169
        return $result;
17✔
170
    }
171
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc