Overview

Namespaces

  • PHP
  • XSLTBenchmarking
    • Reports
    • RunnerConsole
    • TestsGenerator
    • TestsRunner

Classes

  • AMemoryUsageDriver
  • AProcessorDriver
  • Controlor
  • Libxslt1123phpProcessorDriver
  • Libxslt1126phpProcessorDriver
  • LinuxMemoryUsageDriver
  • MemoryUsage
  • MSXML30ProcessorDriver
  • MSXML60ProcessorDriver
  • Params
  • Processor
  • Runner
  • Sablotron103cmdProcessorDriver
  • Saxon655ProcessorDriver
  • SaxonHE9402ProcessorDriver
  • Test
  • TestRunner
  • WindowsMemoryUsageDriver
  • Xalan271ProcessorDriver
  • XmlParamsDriver
  • Xsltproc1123ProcessorDriver
  • Xsltproc1126ProcessorDriver
  • XT20051206ProcessorDriver

Interfaces

  • IParamsDriver
  • Overview
  • Namespace
  • Class
  • Tree
  • Todo
  1: <?php
  2: 
  3: /**
  4:  * XSLT Benchmarking
  5:  * @link https://github.com/masicek/XSLT-Benchmarking
  6:  * @author Viktor Mašíček <viktor@masicek.net>
  7:  * @license "New" BSD License
  8:  */
  9: 
 10: namespace XSLTBenchmarking\TestsRunner;
 11: 
 12: require_once ROOT . '/Exceptions.php';
 13: require_once LIBS . '/PhpPath/PhpPath.min.php';
 14: 
 15: use PhpPath\P;
 16: 
 17: /**
 18:  * Class for control that two files has same content.
 19:  * For XML, HTML, XHTML etc. do normalize both files before comapring.
 20:  *
 21:  * @author Viktor Mašíček <viktor@masicek.net>
 22:  */
 23: class Controlor
 24: {
 25: 
 26: 
 27:     /**
 28:      * Check, if set files have same content.
 29:      * For XML, HTML, XHTML etc. do normalize both files before comapring.
 30:      *
 31:      * @param string $filePath1 Path of the first file
 32:      * @param string $filePath2 Path of the second file
 33:      *
 34:      * @return bool
 35:      */
 36:     public function isSame($filePath1, $filePath2)
 37:     {
 38:         P::mcf($filePath1);
 39:         P::mcf($filePath2);
 40: 
 41:         $content1 = file_get_contents($filePath1);
 42:         $content2 = file_get_contents($filePath2);
 43: 
 44:         // unify EOL
 45:         $content1 = str_replace("\r\n", "\n", $content1);
 46:         $content2 = str_replace("\r\n", "\n", $content2);
 47: 
 48:         // normalize
 49:         $extension1 = strtolower(pathinfo($filePath1, PATHINFO_EXTENSION));
 50:         if ($extension1 == 'xml' || $extension1 == 'html')
 51:         {
 52:             $content1 = $this->normalizeXml($content1, $extension1);
 53:         }
 54:         else
 55:         {
 56:             // unify possible declaration in "non XML files"
 57:             $content1 = $this->unifyDeclaration($content1);
 58:         }
 59: 
 60:         $extension2 = strtolower(pathinfo($filePath2, PATHINFO_EXTENSION));
 61:         if ($extension2 == 'xml' || $extension2 == 'html')
 62:         {
 63:             $content2 = $this->normalizeXml($content2, $extension2);
 64:         }
 65:         else
 66:         {
 67:             // unify possible declaration in "non XML files"
 68:             $content2 = $this->unifyDeclaration($content2);
 69:         }
 70: 
 71:         return $content1 == $content2;
 72:     }
 73: 
 74: 
 75:     /**
 76:      * If content is XML, then return normalized XML input content.
 77:      *      - remove insignificant whitespaces
 78:      *      - sort attributes alphabetical
 79:      * If content is not XML, return input content.
 80:      *
 81:      * @param string $inputContent Normalizing content
 82:      * @param string $extension Extension of file from withc is content
 83:      *
 84:      * @return string
 85:      */
 86:     private function normalizeXml($inputContent, $extension)
 87:     {
 88:         // add declaration, if not presented for XML
 89:         if ($extension == 'xml')
 90:         {
 91:             // get begin with possible declaration
 92:             $beginEndIdx = strpos($inputContent, '>');
 93:             $begin = substr($inputContent, 0, $beginEndIdx + 1);
 94:             // clean begin (e.g. for UTF-16)
 95:             $begin = preg_replace('/[^ a-zA-Z0-9?"\'.=<>-]/', '', $begin);
 96:             if (preg_match('/<\?xml[^?]+\?>/', $begin) === 0)
 97:             {
 98:                 $inputContent = '<?xml version="1.0" encoding="UTF-8" ?>' . $inputContent;
 99:             }
100:         }
101: 
102:         // remove insignificant whitespaces
103:         // simplier empty elements ('<el></el>' => '<el/>')
104:         // simplier attributes ('att   =  "aaa"    att2="bbb"' => 'att="aaa" att2="bbb"')
105:         $dom = new \DOMDocument();
106:         $dom->preserveWhiteSpace = FALSE;
107:         // catch error/warning/notice during reading content as XML or HTML
108:         set_error_handler(array($this, 'errorHandler'));
109:         try
110:         {
111:             if ($extension == 'xml')
112:             {
113:                 $dom->loadXml($inputContent);
114:             }
115:             if ($extension == 'html')
116:             {
117:                 $dom->loadHTML($inputContent);
118:                 $outputContent = $dom->saveXML();
119:                 $dom->loadXml($outputContent);
120:             }
121:         }
122:         catch (\Exception $e)
123:         {
124:             restore_error_handler();
125:             // input is not XML or HTML
126:             return $inputContent;
127:         }
128:         restore_error_handler();
129:         $outputContent = $dom->saveXML();
130: 
131:         // normalize empty atribute ('att' => 'att=""')
132:         // TODO
133: 
134:         // sort attributes
135:         $outputContent = preg_replace_callback('#<[^/?][^>]*>#', array($this, 'sortAttributes'), $outputContent);
136: 
137:         $outputContent = $this->unifyDeclaration($outputContent);
138: 
139:         return $outputContent;
140:     }
141: 
142: 
143:     /**
144:      * Unify declaration of content. If any declaration are not in content, return unchanged it.
145:      *
146:      * @param string $content
147:      *
148:      * @return string
149:      */
150:     private function unifyDeclaration($content)
151:     {
152:         $outputContent = $content;
153:         $declarationLast = strpos($outputContent, '?>');
154:         if ($declarationLast !== FALSE)
155:         {
156:             $declaration = substr($outputContent, 0, $declarationLast);
157:             $declarationUnify = trim($declaration);
158:             $declarationUnify = strtolower($declarationUnify);
159:             $outputContent = $declarationUnify . substr($outputContent, $declarationLast);
160:         }
161: 
162:         return $outputContent;
163:     }
164: 
165: 
166:     /**
167:      * Normalize element
168:      *      - remove insignificant whitespaces
169:      *      - sort attributes alphabetical
170:      *
171:      * @param array $matches The first value is parsed element
172:      *
173:      * @return string
174:      */
175:     private function sortAttributes($matches)
176:     {
177:         $input = $matches[0];
178: 
179:         // begin
180:         $beginLast = strpos($input, ' ');
181:         $beginLast = $beginLast ?: strpos($input, '/>');
182:         $beginLast = $beginLast ?: strpos($input, '>');
183:         $begin = substr($input, 0, $beginLast);
184: 
185:         // end
186:         $endFirst = strrpos($input, '/>');
187:         $endFirst = $endFirst ?: strrpos($input, '>');
188:         $end = substr($input, $endFirst);
189: 
190:         // attributes
191:         $attributes = $input;
192:         $attributes = str_replace($begin, '', $attributes);
193:         $attributes = str_replace($end, '', $attributes);
194:         if ($attributes)
195:         {
196:             preg_match_all('/[^ ]+="[^"]*"/', $attributes, $matches);
197:             $attributes = $matches[0];
198:             $attributes = array_filter($attributes);
199:             sort($attributes);
200:             $attributes = implode(' ', $attributes);
201:         }
202: 
203:         if ($attributes)
204:         {
205:             $output = $begin . ' ' . $attributes . $end;
206:         }
207:         else
208:         {
209:             $output = $begin . $end;
210:         }
211: 
212:         return $output;
213:     }
214: 
215: 
216:     /**
217:      * Handling of error during reading XML or HTML file.
218:      *
219:      * @param type $errno
220:      * @param type $errstr
221:      *
222:      * @return void
223:      */
224:     public function errorHandler($errno, $errstr)
225:     {
226:         throw new \Exception('Error handler');
227:     }
228: 
229: 
230: }
231: 
XSTL Benchmarking API documentation generated by ApiGen.
Generated using the TokenReflection library.