Skip to content

Commit 4029223

Browse files
committed
Merge pull request #7 from fusionspim/hotfix/improve-xml-validation
Improve XML validation
2 parents b6c197f + 340e9d1 commit 4029223

File tree

3 files changed

+167
-1
lines changed

3 files changed

+167
-1
lines changed

src/Xml.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ public static function escape($value)
2626
/**
2727
* Validates the XML file against the specified XSD schema
2828
* Also formats/normalizes the file to improve human readability and ease diff'ing
29+
* Formatting will only occur if the XML is valid, otherwise DOMDocument truncates the data making debugging impossible.
2930
*
3031
* @param $filePath
3132
* @param $schemaPath
@@ -35,6 +36,8 @@ public static function validate($filePath)
3536
{
3637
if (! file_exists($filePath)) {
3738
throw new XmlException('XML file missing');
39+
} elseif (! is_readable($filePath)) {
40+
throw new XmlException('XML file is not readable');
3841
}
3942

4043
// domdocument dies silently when given a big (1.7GB) file, though known to cope with 892Mb
@@ -55,13 +58,14 @@ public static function validate($filePath)
5558
$dom->formatOutput = true;
5659
$dom->load($filePath);
5760
$dom->normalizeDocument();
58-
$dom->save($filePath);
5961

6062
restore_error_handler();
6163

6264
if (! $dom->schemaValidate(realpath(__DIR__ . '/../xsd/catalog.xsd'))) {
6365
throw new XmlException(static::errorSummary());
6466
}
67+
68+
return $dom->save($filePath) > 0;
6569
}
6670

6771
/**

tests/XmlTest.php

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?php
2+
namespace DemandwareXml\Test;
3+
4+
use \PHPUnit_Framework_TestCase;
5+
use \DemandwareXml\Xml;
6+
use \DemandwareXml\XmlException;
7+
8+
class XmlTest extends PHPUnit_Framework_TestCase
9+
{
10+
public function testValidateXml()
11+
{
12+
$xmlPath = __DIR__ . '/fixtures/products.xml';
13+
14+
$this->assertTrue(Xml::validate($xmlPath));
15+
}
16+
17+
/**
18+
* @expectedException \DemandwareXml\XmlException
19+
* @expectedExceptionRegExp /xmlParseEntityRef: no name/
20+
*/
21+
public function testValidateInvalidXml()
22+
{
23+
$xmlPath = __DIR__ . '/fixtures/invalid_items.xml';
24+
25+
$this->assertFalse(Xml::validate($xmlPath));
26+
}
27+
}
Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<catalog xmlns="http://www.demandware.com/xml/impex/catalog/2006-10-31" catalog-id="TestCatalog">
3+
<product product-id="PRODUCT123">
4+
<upc>500000000000</upc>
5+
<min-order-quantity>1</min-order-quantity>
6+
<step-quantity>1</step-quantity>
7+
<display-name xml:lang="x-default">Product number 123</display-name>
8+
<long-description xml:lang="x-default">The description for an example product! &amp;bull; Bullet Point & this is broken</long-description>
9+
<online-flag>true</online-flag>
10+
<online-from>2015-01-23T01:23:45</online-from>
11+
<online-to>2025-01-23T01:23:45</online-to>
12+
<searchable-flag>false</searchable-flag>
13+
<brand>SampleBrand™</brand>
14+
<search-rank>1</search-rank>
15+
<sitemap-included-flag>true</sitemap-included-flag>
16+
<sitemap-changefrequency>weekly</sitemap-changefrequency>
17+
<sitemap-priority>0.5</sitemap-priority>
18+
<page-attributes>
19+
<page-title xml:lang="x-default">Amazing Product</page-title>
20+
<page-description xml:lang="x-default">Buy our Product today!</page-description>
21+
<page-keywords xml:lang="x-default">Product, test, example</page-keywords>
22+
<page-url xml:lang="x-default">http://example.com/product/123</page-url>
23+
</page-attributes>
24+
<custom-attributes>
25+
<custom-attribute attribute-id="boolTest">true</custom-attribute>
26+
<custom-attribute attribute-id="multiWow">
27+
<value>so</value>
28+
<value>such</value>
29+
<value>many</value>
30+
<value>much</value>
31+
<value>very</value>
32+
</custom-attribute>
33+
<custom-attribute attribute-id="primaryImage">product-123.png</custom-attribute>
34+
<custom-attribute attribute-id="type">Examples</custom-attribute>
35+
<custom-attribute attribute-id="zzz">Should be exported last within custom-attributes</custom-attribute>
36+
</custom-attributes>
37+
<variations>
38+
<attributes>
39+
<shared-variation-attribute variation-attribute-id="AT001" attribute-id="AT001"/>
40+
<shared-variation-attribute variation-attribute-id="AT002" attribute-id="AT002"/>
41+
</attributes>
42+
<variants>
43+
<variant product-id="SKU0000001"/>
44+
<variant product-id="SKU0000002"/>
45+
<variant product-id="SKU0000003" default="true"/>
46+
</variants>
47+
</variations>
48+
<classification-category catalog-id="TestCatalog">CAT123</classification-category>
49+
</product>
50+
<product product-id="SET123">
51+
<upc>500000000001</upc>
52+
<min-order-quantity>1</min-order-quantity>
53+
<step-quantity>1</step-quantity>
54+
<display-name xml:lang="x-default">Set number 123</display-name>
55+
<long-description xml:lang="x-default">The description for an example set! &amp;bull; Bullet Point</long-description>
56+
<online-flag>true</online-flag>
57+
<online-from>2015-01-23T01:23:45</online-from>
58+
<online-to>2025-01-23T01:23:45</online-to>
59+
<searchable-flag>false</searchable-flag>
60+
<brand>SampleBrand™</brand>
61+
<search-rank>1</search-rank>
62+
<sitemap-included-flag>true</sitemap-included-flag>
63+
<sitemap-changefrequency>weekly</sitemap-changefrequency>
64+
<sitemap-priority>0.5</sitemap-priority>
65+
<page-attributes>
66+
<page-title xml:lang="x-default">Amazing Set</page-title>
67+
<page-description xml:lang="x-default">Buy our Set today!</page-description>
68+
<page-keywords xml:lang="x-default">Set, test, example</page-keywords>
69+
<page-url xml:lang="x-default">http://example.com/set/123</page-url>
70+
</page-attributes>
71+
<custom-attributes>
72+
<custom-attribute attribute-id="boolTest">true</custom-attribute>
73+
<custom-attribute attribute-id="multiWow">
74+
<value>so</value>
75+
<value>such</value>
76+
<value>many</value>
77+
<value>much</value>
78+
<value>very</value>
79+
</custom-attribute>
80+
<custom-attribute attribute-id="primaryImage">set-123.png</custom-attribute>
81+
<custom-attribute attribute-id="type">Examples</custom-attribute>
82+
<custom-attribute attribute-id="zzz">Should be exported last within custom-attributes</custom-attribute>
83+
</custom-attributes>
84+
<product-set-products>
85+
<product-set-product product-id="PRODUCT123"/>
86+
<product-set-product product-id="PRODUCT456"/>
87+
</product-set-products>
88+
<classification-category catalog-id="TestCatalog">CAT123</classification-category>
89+
</product>
90+
<product product-id="BUNDLE123">
91+
<upc>500000000002</upc>
92+
<min-order-quantity>1</min-order-quantity>
93+
<step-quantity>1</step-quantity>
94+
<display-name xml:lang="x-default">Bundle number 123</display-name>
95+
<long-description xml:lang="x-default">The description for an example bundle! &amp;bull; Bullet Point</long-description>
96+
<online-flag>true</online-flag>
97+
<online-from>2015-01-23T01:23:45</online-from>
98+
<online-to>2025-01-23T01:23:45</online-to>
99+
<searchable-flag>false</searchable-flag>
100+
<tax-class-id>TAX_20_00</tax-class-id>
101+
<brand>SampleBrand™</brand>
102+
<search-rank>1</search-rank>
103+
<sitemap-included-flag>true</sitemap-included-flag>
104+
<sitemap-changefrequency>weekly</sitemap-changefrequency>
105+
<sitemap-priority>0.5</sitemap-priority>
106+
<page-attributes>
107+
<page-title xml:lang="x-default">Amazing Bundle</page-title>
108+
<page-description xml:lang="x-default">Buy our Bundle today!</page-description>
109+
<page-keywords xml:lang="x-default">Bundle, test, example</page-keywords>
110+
<page-url xml:lang="x-default">http://example.com/bundle/123</page-url>
111+
</page-attributes>
112+
<custom-attributes>
113+
<custom-attribute attribute-id="boolTest">true</custom-attribute>
114+
<custom-attribute attribute-id="multiWow">
115+
<value>so</value>
116+
<value>such</value>
117+
<value>many</value>
118+
<value>much</value>
119+
<value>very</value>
120+
</custom-attribute>
121+
<custom-attribute attribute-id="primaryImage">bundle-123.png</custom-attribute>
122+
<custom-attribute attribute-id="type">Examples</custom-attribute>
123+
<custom-attribute attribute-id="zzz">Should be exported last within custom-attributes</custom-attribute>
124+
</custom-attributes>
125+
<bundled-products>
126+
<bundled-product product-id="SKU0000001">
127+
<quantity>10</quantity>
128+
</bundled-product>
129+
<bundled-product product-id="SKU0000002">
130+
<quantity>20</quantity>
131+
</bundled-product>
132+
</bundled-products>
133+
<classification-category catalog-id="TestCatalog">CAT123</classification-category>
134+
</product>
135+
</catalog>

0 commit comments

Comments
 (0)