1
<?php
2
/**
3
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
4
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
5
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
6
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
7
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
8
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
9
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
10
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
11
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
12
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
13
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
14
 *
15
 * This software consists of voluntary contributions made by many individuals
16
 * and is licensed under the LGPL. For more information please see
17
 * <http://phing.info>.
18
 */
19

20
/**
21
 * Implements an XmlFileParser.
22
 *
23
 * @author  Siad Ardroumli <siad.ardroumli@gmail.com>
24
 * @package phing.system.io
25
 */
26
class XmlFileParser implements FileParserInterface
27
{
28
    private $keepRoot = true;
29
    private $collapseAttr = true;
30
    private $delimiter = ',';
31

32
    /**
33
     * @param bool $keepRoot
34
     */
35 0
    public function setKeepRoot(bool $keepRoot): void
36
    {
37 0
        $this->keepRoot = $keepRoot;
38
    }
39

40
    /**
41
     * @param bool $collapseAttr
42
     */
43 0
    public function setCollapseAttr(bool $collapseAttr): void
44
    {
45 0
        $this->collapseAttr = $collapseAttr;
46
    }
47

48
    /**
49
     * @param string $delimiter
50
     */
51 0
    public function setDelimiter(string $delimiter): void
52
    {
53 0
        $this->delimiter = $delimiter;
54
    }
55

56
    /**
57
     * {@inheritDoc}
58
     */
59 0
    public function parseFile(PhingFile $file)
60
    {
61 0
        $properties = $this->getProperties($file);
62

63 0
        return $properties->getProperties();
64
    }
65

66
    /**
67
     * Parses an XML file and returns properties
68
     *
69
     * @param PhingFile $file
70
     *
71
     * @throws IOException
72
     * @return Properties
73
     */
74 0
    private function getProperties(PhingFile $file)
75
    {
76
        // load() already made sure that file is readable
77
        // but we'll double check that when reading the file into
78
        // an array
79

80 0
        if ((@file($file)) === false) {
81 0
            throw new IOException("Unable to parse contents of $file");
82
        }
83

84 0
        $prop = new Properties();
85

86 0
        $xml = simplexml_load_string(file_get_contents($file));
87

88 0
        if ($xml === false) {
89 0
            throw new IOException("Unable to parse XML file $file");
90
        }
91

92 0
        $path = [];
93

94 0
        if ($this->keepRoot) {
95 0
            $path[] = dom_import_simplexml($xml)->tagName;
96

97 0
            $prefix = implode('.', $path);
98

99 0
            if (!empty($prefix)) {
100 0
                $prefix .= '.';
101
            }
102

103
            // Check for attributes
104 0
            foreach ($xml->attributes() as $attribute => $val) {
105 0
                if ($this->collapseAttr) {
106 0
                    $prop->setProperty($prefix . (string) $attribute, (string) $val);
107 0
                } else {
108 0
                    $prop->setProperty($prefix . "($attribute)", (string) $val);
109
                }
110
            }
111
        }
112

113 0
        $this->addNode($xml, $path, $prop);
114

115 0
        return $prop;
116
    }
117

118
    /**
119
     * Adds an XML node
120
     *
121
     * @param SimpleXMLElement $node
122
     * @param array $path Path to this node
123
     * @param Properties $prop Properties will be added as they are found (by reference here)
124
     *
125
     * @return void
126
     */
127 0
    private function addNode($node, $path, $prop)
128
    {
129 0
        foreach ($node as $tag => $value) {
130 0
            $prefix = implode('.', $path);
131

132 0
            if ($prefix !== '') {
133 0
                $prefix .= '.';
134
            }
135

136
            // Check for attributes
137 0
            foreach ($value->attributes() as $attribute => $val) {
138 0
                if ($this->collapseAttr) {
139 0
                    $prop->setProperty($prefix . "$tag.$attribute", (string) $val);
140 0
                } else {
141 0
                    $prop->setProperty($prefix . "$tag($attribute)", (string) $val);
142
                }
143
            }
144

145
            // Add tag
146 0
            if (count($value->children())) {
147 0
                $this->addNode($value, array_merge($path, [$tag]), $prop);
148 0
            } else {
149 0
                $val = (string) $value;
150

151
                /* Check for * and ** on 'exclude' and 'include' tag / ant seems to do this? could use FileSet here
152
                if ($tag == 'exclude') {
153
                }*/
154

155
                // When property already exists, i.e. multiple xml tag
156
                // <project>
157
                //    <exclude>file/a.php</exclude>
158
                //    <exclude>file/a.php</exclude>
159
                // </project>
160
                //
161
                // Would be come project.exclude = file/a.php,file/a.php
162 0
                $p = empty($prefix) ? $tag : $prefix . $tag;
163 0
                $prop->append($p, (string) $val, $this->delimiter);
164
            }
165
        }
166
    }
167
}

Read our documentation on viewing source code .

Loading