Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
38 / 38
100.00% covered (success)
100.00%
8 / 8
CRAP
100.00% covered (success)
100.00%
1 / 1
XMLReader
100.00% covered (success)
100.00%
38 / 38
100.00% covered (success)
100.00%
8 / 8
18
100.00% covered (success)
100.00%
1 / 1
 getDomFromZip
100.00% covered (success)
100.00%
9 / 9
100.00% covered (success)
100.00%
1 / 1
3
 getDomFromString
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
 getElements
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
3
 getElement
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
2
 getAttribute
100.00% covered (success)
100.00%
9 / 9
100.00% covered (success)
100.00%
1 / 1
5
 getValue
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
2
 countElements
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 elementExists
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3/**
4 * This file is part of PHPProject - A pure PHP library for reading and writing
5 * project management files.
6 *
7 * PHPProject is free software distributed under the terms of the GNU Lesser
8 * General Public License version 3 as published by the Free Software Foundation.
9 *
10 * For the full copyright and license information, please read the LICENSE
11 * file that was distributed with this source code. For the full list of
12 * contributors, visit https://github.com/PHPOffice/PHPProject/contributors.
13 *
14 * @link        https://github.com/PHPOffice/PHPProject
15 * @copyright   2010-2014 PHPProject contributors
16 * @license     http://www.gnu.org/licenses/lgpl.txt LGPL version 3
17 */
18
19declare(strict_types=1);
20
21namespace PhpOffice\PhpProject\Shared;
22
23/**
24 * XML Reader wrapper
25 *
26 * @since   0.10.0
27 */
28class XMLReader
29{
30    /**
31     * DOMDocument object
32     *
33     * @var \DOMDocument
34     */
35    private $dom = null;
36
37    /**
38     * DOMXpath object
39     *
40     * @var \DOMXpath
41     */
42    private $xpath = null;
43
44    /**
45     * Get DOMDocument from ZipArchive
46     *
47     * @param string $zipFile
48     * @param string $xmlFile
49     * @return \DOMDocument|false
50     * @throws \Exception
51     */
52    public function getDomFromZip(string $zipFile, string $xmlFile)
53    {
54        if (file_exists($zipFile) === false) {
55            throw new \Exception('Cannot find archive file.');
56        }
57
58        $zip = new \ZipArchive();
59        $zip->open($zipFile);
60        $content = $zip->getFromName($xmlFile);
61        $zip->close();
62
63        if ($content === false) {
64            return false;
65        } else {
66            return $this->getDomFromString($content);
67        }
68    }
69
70    /**
71     * Get DOMDocument from content string
72     *
73     * @param string $content
74     * @return \DOMDocument
75     */
76    public function getDomFromString(string $content): \DOMDocument
77    {
78        $this->dom = new \DOMDocument();
79        $this->dom->loadXML($content);
80
81        return $this->dom;
82    }
83
84    /**
85     * Get elements
86     *
87     * @param string $path
88     * @param \DOMNode $contextNode
89     * @return \DOMNodeList|array
90     */
91    public function getElements(string $path, ?\DOMNode $contextNode = null)
92    {
93        if ($this->dom === null) {
94            return array();
95        }
96        if ($this->xpath === null) {
97            $this->xpath = new \DOMXpath($this->dom);
98        }
99
100        return $this->xpath->query($path, $contextNode);
101    }
102
103    /**
104     * Get element
105     *
106     * @param string $path
107     * @param \DOMNode|null $contextNode
108     * @return \DOMElement|null
109     */
110    public function getElement(string $path, ?\DOMNode $contextNode = null): ?\DOMElement
111    {
112        $elements = $this->getElements($path, $contextNode);
113        $item = $elements->item(0);
114        if ($item instanceof \DOMElement) {
115            return $item;
116        }
117        return null;
118    }
119
120    /**
121     * Get element attribute
122     *
123     * @param string $attribute
124     * @param \DOMElement|null $contextNode
125     * @param string $path
126     * @return string|null
127     */
128    public function getAttribute(string $attribute, ?\DOMElement $contextNode = null, ?string $path = null): ?string
129    {
130        $return = null;
131        if ($path !== null) {
132            $elements = $this->getElements($path, $contextNode);
133            if ($elements->length > 0) {
134                /** @var \DOMElement $node Type hint */
135                $node = $elements->item(0);
136                $return = $node->getAttribute($attribute);
137            }
138        } else {
139            if ($contextNode !== null) {
140                $return = $contextNode->getAttribute($attribute);
141            }
142        }
143
144        return ($return == '') ? null : $return;
145    }
146
147    /**
148     * Get element value
149     *
150     * @param string $path
151     * @param \DOMElement $contextNode
152     * @return string|null
153     */
154    public function getValue(string $path, ?\DOMElement $contextNode = null): ?string
155    {
156        $elements = $this->getElements($path, $contextNode);
157        if ($elements->length > 0) {
158            return $elements->item(0)->nodeValue;
159        } else {
160            return null;
161        }
162    }
163
164    /**
165     * Count elements
166     *
167     * @param string $path
168     * @param \DOMElement $contextNode
169     * @return integer
170     */
171    public function countElements(string $path, ?\DOMElement $contextNode = null): int
172    {
173        $elements = $this->getElements($path, $contextNode);
174
175        return $elements->length;
176    }
177
178    /**
179     * Element exists
180     *
181     * @param string $path
182     * @param \DOMElement $contextNode
183     * @return boolean
184     */
185    public function elementExists(string $path, ?\DOMElement $contextNode = null): bool
186    {
187        return $this->getElements($path, $contextNode)->length > 0;
188    }
189}