Overview

Namespaces

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

Classes

  • Convertor
  • HtmlConvertorDriver
  • Merger
  • Printer
  • Report

Interfaces

  • IConvertorDriver
  • 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\Reports;
 11: 
 12: require_once ROOT . '/Exceptions.php';
 13: require_once LIBS . '/PhpPath/PhpPath.min.php';
 14: 
 15: use PhpPath\P;
 16: 
 17: /**
 18:  * Merging of more reported tests into one XML file.
 19:  *
 20:  * @author Viktor Mašíček <viktor@masicek.net>
 21:  */
 22: class Merger
 23: {
 24: 
 25: 
 26:     /**
 27:      * List of reports for generating
 28:      *
 29:      * @var arry of \SimpleXML
 30:      */
 31:     private $reports;
 32: 
 33: 
 34:     /**
 35:      * Make merge of all added reports, save result into file and
 36:      * return path of generated file
 37:      *
 38:      * @param string $outputDirPath Path of directory for generating mergered report
 39:      *
 40:      * @return string
 41:      */
 42:     public function merge($outputDirPath)
 43:     {
 44:         // make name of output
 45:         P::cd($outputDirPath);
 46:         $outputPath = P::m($outputDirPath, date('Y-m-d-H-i-s'). '-merge' . '.xml');
 47: 
 48:         $mergeredReports = $this->getMergeredReport();
 49:         $this->saveMegeredReports($outputPath, $mergeredReports);
 50: 
 51:         return $outputPath;
 52:     }
 53: 
 54: 
 55:     /**
 56:      * Add report into list of mergered reports
 57:      *
 58:      * @param string $path Path of XML file with reports
 59:      *
 60:      * @throws \XSLTBenchmarking\InvalidArgumentException Wrong format of file with params
 61:      * @return void
 62:      */
 63:     public function addReportFile($path)
 64:     {
 65:         $path = P::mcf($path);
 66: 
 67:         // validate
 68:         $dom = new \DOMDocument();
 69:         $dom->load($path);
 70:         try {
 71:             $dom->schemaValidate(P::m(__DIR__, 'Report.xsd'));
 72:         } catch (\Exception $e) {
 73:             $error = libxml_get_last_error();
 74:             throw new \XSLTBenchmarking\InvalidArgumentException(
 75:                 'File "' . $path . '" has wrong format: ' . $error->message
 76:             );
 77:         }
 78: 
 79:         // make SimpleXML
 80:         $report = new \SimpleXMLElement($path, 0, TRUE);
 81: 
 82:         $this->reports[] = $report;
 83:     }
 84: 
 85: 
 86:     /**
 87:      * Merge reports into one SimpleXML object.
 88:      *
 89:      * @return \SimpleXMLElement
 90:      */
 91:     private function getMergeredReport()
 92:     {
 93:         $mergeEl = new \SimpleXMLElement('<?xml version="1.0" encoding="UTF-8"?><reports></reports>');
 94: 
 95:         // skeleton
 96:         $globalEl = $mergeEl->addChild('global');
 97:         $processorsListEl = $globalEl->addChild('processors');
 98:         $testsListEl = $mergeEl->addChild('tests');
 99: 
100:         foreach ($this->reports as $report)
101:         {
102:             // processors
103:             $processors = $report->xpath('//global/processors');
104:             $this->copyChilds($processors[0], $processorsListEl, array('processor|name'));
105: 
106:             // tests
107:             $tests = $report->xpath('//tests');
108:             $this->copyChilds($tests[0], $testsListEl, array('test|name', 'processor|name', 'input|input|expectedOutput'));
109:         }
110: 
111:         return $mergeEl;
112:     }
113: 
114: 
115:     /**
116:      * Copy children elements from source element into destination element.
117:      * Runction is called recursively if $childrenInfos have more than one value.
118:      *
119:      * @param \SimpleXMLElement $sourceElement Source XML element
120:      * @param \SimpleXMLElement $destinationElement Destionation XML element
121:      * @param array $childrenInfos Information for copy.
122:      * Each value is name of copied element and atributes for comapring (separated by '|').
123:      *
124:      * @return void
125:      */
126:     private function copyChilds(
127:         \SimpleXMLElement $sourceElement,
128:         \SimpleXMLElement $destinationElement,
129:         array $childrenInfos = array()
130:     )
131:     {
132:         $childInfo = array_shift($childrenInfos);
133:         $infos = explode('|', $childInfo);
134:         $childName = array_shift($infos);
135: 
136:         $childrenElements = $sourceElement->xpath($childName);
137:         foreach ($childrenElements as $childElement)
138:         {
139:             $checkRule = array();
140:             foreach ($infos as $info)
141:             {
142:                 $checkRule[] = '@' . $info . '="' . (string)$childElement[$info] . '"';
143:             }
144:             if ($checkRule)
145:             {
146:                 $checkRule = '[' . implode(' and ', $checkRule) . ']';
147:             }
148: 
149:             $destionationChildElements = $destinationElement->xpath($childName . $checkRule);
150:             if (count($destionationChildElements) == 0)
151:             {
152:                 $addedElement = $destinationElement->addChild($childName);
153:             }
154:             else
155:             {
156:                 $addedElement = $destionationChildElements[0];
157:             }
158: 
159:             // copy attribute - newer values are preferred
160:             $this->copyOrReplaceAttributes($childElement, $addedElement);
161: 
162:             // copy children
163:             if (count($childrenInfos) > 0)
164:             {
165:                 $this->copyChilds($childElement, $addedElement, $childrenInfos);
166:             }
167:         }
168:     }
169: 
170: 
171:     /**
172:      * Copy element from source element into destination element.
173:      * If attribute existed in destination element, than its value is replaced by newer.
174:      *
175:      * @param \SimpleXMLElement $sourceElement Source XML element
176:      * @param \SimpleXMLElement $destinationElement Destionation XML element
177:      *
178:      * @return void
179:      */
180:     private function copyOrReplaceAttributes(\SimpleXMLElement $sourceElement, \SimpleXMLElement $destinationElement)
181:     {
182:         foreach ($sourceElement->attributes() as $name => $value)
183:         {
184:             $destinationElement[$name] = $value;
185:         }
186:     }
187: 
188: 
189:     /**
190:      * Save mergered reports into file. XML is indented.
191:      *
192:      * @param sring $outputPath Path of file
193:      * @param \SimpleXMLElement $mergeredReports Report for saving
194:      *
195:      * @return void
196:      */
197:     private function saveMegeredReports($outputPath, \SimpleXMLElement $mergeredReports)
198:     {
199:         // save + make indent
200:         $dom = dom_import_simplexml($mergeredReports)->ownerDocument;
201:         $dom->formatOutput = TRUE;
202:         $dom->save($outputPath);
203:     }
204: 
205: 
206: }
207: 
XSTL Benchmarking API documentation generated by ApiGen.
Generated using the TokenReflection library.