Skip to content

Commit 7473981

Browse files
Bassterogizanagi
authored andcommitted
[Config] extracted the xml parsing from XmlUtils::loadFile into XmlUtils::parse
1 parent ec8edee commit 7473981

File tree

4 files changed

+98
-16
lines changed

4 files changed

+98
-16
lines changed

src/Symfony/Component/Config/Tests/Util/XmlUtilsTest.php

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,13 +55,27 @@ public function testLoadFile()
5555
XmlUtils::loadFile($fixtures.'valid.xml', array($mock, 'validate'));
5656
$this->fail();
5757
} catch (\InvalidArgumentException $e) {
58-
$this->assertContains('is not valid', $e->getMessage());
58+
$this->assertRegExp('/The XML file "[\w:\/\\\.]+" is not valid\./', $e->getMessage());
5959
}
6060

6161
$this->assertInstanceOf('DOMDocument', XmlUtils::loadFile($fixtures.'valid.xml', array($mock, 'validate')));
6262
$this->assertSame(array(), libxml_get_errors());
6363
}
6464

65+
/**
66+
* @expectedException \Symfony\Component\Config\Util\Exception\InvalidXmlException
67+
* @expectedExceptionMessage The XML is not valid
68+
*/
69+
public function testParseWithInvalidValidatorCallable()
70+
{
71+
$fixtures = __DIR__.'/../Fixtures/Util/';
72+
73+
$mock = $this->getMockBuilder(__NAMESPACE__.'\Validator')->getMock();
74+
$mock->expects($this->once())->method('validate')->willReturn(false);
75+
76+
XmlUtils::parse(file_get_contents($fixtures.'valid.xml'), array($mock, 'validate'));
77+
}
78+
6579
public function testLoadFileWithInternalErrorsEnabled()
6680
{
6781
$internalErrors = libxml_use_internal_errors(true);
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
/*
3+
* This file is part of the Symfony package.
4+
*
5+
* (c) Fabien Potencier <[email protected]>
6+
*
7+
* For the full copyright and license information, please view the LICENSE
8+
* file that was distributed with this source code.
9+
*/
10+
11+
namespace Symfony\Component\Config\Util\Exception;
12+
13+
/**
14+
* Exception class for when XML parsing with an XSD schema file path or a callable validator produces errors unrelated
15+
* to the actual XML parsing.
16+
*
17+
* @author Ole Rößner <[email protected]>
18+
*/
19+
class InvalidXmlException extends XmlParsingException
20+
{
21+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Config\Util\Exception;
13+
14+
/**
15+
* Exception class for when XML cannot be parsed properly.
16+
*
17+
* @author Ole Rößner <[email protected]>
18+
*/
19+
class XmlParsingException extends \InvalidArgumentException
20+
{
21+
}

src/Symfony/Component/Config/Util/XmlUtils.php

Lines changed: 41 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,17 @@
1111

1212
namespace Symfony\Component\Config\Util;
1313

14+
use Symfony\Component\Config\Util\Exception\InvalidXmlException;
15+
use Symfony\Component\Config\Util\Exception\XmlParsingException;
16+
1417
/**
1518
* XMLUtils is a bunch of utility methods to XML operations.
1619
*
1720
* This class contains static methods only and is not meant to be instantiated.
1821
*
1922
* @author Fabien Potencier <[email protected]>
2023
* @author Martin Hasoň <[email protected]>
24+
* @author Ole Rößner <[email protected]>
2125
*/
2226
class XmlUtils
2327
{
@@ -29,27 +33,23 @@ private function __construct()
2933
}
3034

3135
/**
32-
* Loads an XML file.
36+
* Parses an XML string.
3337
*
34-
* @param string $file An XML file path
38+
* @param string $content An XML string
3539
* @param string|callable|null $schemaOrCallable An XSD schema file path, a callable, or null to disable validation
3640
*
3741
* @return \DOMDocument
3842
*
39-
* @throws \InvalidArgumentException When loading of XML file returns error
40-
* @throws \RuntimeException When DOM extension is missing
43+
* @throws \Symfony\Component\Config\Util\Exception\XmlParsingException When parsing of XML file returns error
44+
* @throws \Symfony\Component\Config\Util\Exception\InvalidXmlException When parsing of XML with schema or callable produces any errors unrelated to the XML parsing itself
45+
* @throws \RuntimeException When DOM extension is missing
4146
*/
42-
public static function loadFile($file, $schemaOrCallable = null)
47+
public static function parse($content, $schemaOrCallable = null)
4348
{
4449
if (!extension_loaded('dom')) {
4550
throw new \RuntimeException('Extension DOM is required.');
4651
}
4752

48-
$content = @file_get_contents($file);
49-
if ('' === trim($content)) {
50-
throw new \InvalidArgumentException(sprintf('File %s does not contain valid XML, it is empty.', $file));
51-
}
52-
5353
$internalErrors = libxml_use_internal_errors(true);
5454
$disableEntities = libxml_disable_entity_loader(true);
5555
libxml_clear_errors();
@@ -59,7 +59,7 @@ public static function loadFile($file, $schemaOrCallable = null)
5959
if (!$dom->loadXML($content, LIBXML_NONET | (defined('LIBXML_COMPACT') ? LIBXML_COMPACT : 0))) {
6060
libxml_disable_entity_loader($disableEntities);
6161

62-
throw new \InvalidArgumentException(implode("\n", static::getXmlErrors($internalErrors)));
62+
throw new XmlParsingException(implode("\n", static::getXmlErrors($internalErrors)));
6363
}
6464

6565
$dom->normalizeDocument();
@@ -69,7 +69,7 @@ public static function loadFile($file, $schemaOrCallable = null)
6969

7070
foreach ($dom->childNodes as $child) {
7171
if (XML_DOCUMENT_TYPE_NODE === $child->nodeType) {
72-
throw new \InvalidArgumentException('Document types are not allowed.');
72+
throw new XmlParsingException('Document types are not allowed.');
7373
}
7474
}
7575

@@ -90,15 +90,15 @@ public static function loadFile($file, $schemaOrCallable = null)
9090
} else {
9191
libxml_use_internal_errors($internalErrors);
9292

93-
throw new \InvalidArgumentException('The schemaOrCallable argument has to be a valid path to XSD file or callable.');
93+
throw new XmlParsingException('The schemaOrCallable argument has to be a valid path to XSD file or callable.');
9494
}
9595

9696
if (!$valid) {
9797
$messages = static::getXmlErrors($internalErrors);
9898
if (empty($messages)) {
99-
$messages = array(sprintf('The XML file "%s" is not valid.', $file));
99+
throw new InvalidXmlException('The XML is not valid.', 0, $e);
100100
}
101-
throw new \InvalidArgumentException(implode("\n", $messages), 0, $e);
101+
throw new XmlParsingException(implode("\n", $messages), 0, $e);
102102
}
103103
}
104104

@@ -108,6 +108,32 @@ public static function loadFile($file, $schemaOrCallable = null)
108108
return $dom;
109109
}
110110

111+
/**
112+
* Loads an XML file.
113+
*
114+
* @param string $file An XML file path
115+
* @param string|callable|null $schemaOrCallable An XSD schema file path, a callable, or null to disable validation
116+
*
117+
* @return \DOMDocument
118+
*
119+
* @throws \InvalidArgumentException When loading of XML file returns error
120+
* @throws \Symfony\Component\Config\Util\Exception\XmlParsingException when XML parsing returns any errors
121+
* @throws \RuntimeException When DOM extension is missing
122+
*/
123+
public static function loadFile($file, $schemaOrCallable = null)
124+
{
125+
$content = @file_get_contents($file);
126+
if ('' === trim($content)) {
127+
throw new \InvalidArgumentException(sprintf('File %s does not contain valid XML, it is empty.', $file));
128+
}
129+
130+
try {
131+
return static::parse($content, $schemaOrCallable);
132+
} catch (InvalidXmlException $e) {
133+
throw new XmlParsingException(sprintf('The XML file "%s" is not valid.', $file), 0, $e->getPrevious());
134+
}
135+
}
136+
111137
/**
112138
* Converts a \DomElement object to a PHP array.
113139
*

0 commit comments

Comments
 (0)