/** * Validate and format (if possible) a QTI XML string * * @param string $qti * @return string * @throws QtiModelException */ public static function validateQtiXml($qti) { $returnValue = ''; // render and clean the xml $dom = new DOMDocument('1.0', 'UTF-8'); $dom->formatOutput = true; $dom->preserveWhiteSpace = false; $dom->validateOnParse = false; if ($dom->loadXML($qti)) { $returnValue = $dom->saveXML(); //in debug mode, systematically check if the save QTI is standard compliant if (DEBUG_MODE) { $parserValidator = new Parser($returnValue); $parserValidator->validate(); if (!$parserValidator->isValid()) { common_Logger::w('Invalid QTI output: ' . PHP_EOL . ' ' . $parserValidator->displayErrors()); common_Logger::d(print_r(explode(PHP_EOL, $returnValue), true)); throw new QtiModelException('invalid QTI item XML ' . PHP_EOL . ' ' . $parserValidator->displayErrors()); } } } else { $parserValidator = new Parser($qti); $parserValidator->validate(); if (!$parserValidator->isValid()) { throw new QtiModelException('Wrong QTI item output format'); } } return (string) $returnValue; }
/** * Validate a QTI XML string. * * @param string $qti File path or XML string * @throws QtiModelException */ public static function validateQtiXml($qti) { $dom = self::loadQtiXml($qti); $returnValue = $dom->saveXML(); $parserValidator = new Parser($returnValue); $parserValidator->validate(); if (!$parserValidator->isValid()) { common_Logger::w('Invalid QTI output: ' . PHP_EOL . ' ' . $parserValidator->displayErrors()); throw new QtiModelException('invalid QTI item XML ' . PHP_EOL . ' ' . $parserValidator->displayErrors()); } }
/** * packItem implementation for QTI * @inheritdoc * @see {@link ItemPacker} * @throws InvalidArgumentException * @throws common_Exception */ public function packItem(core_kernel_classes_Resource $item, $lang = "") { $itemPack = null; $path = $this->getPath($item, $lang); $content = $this->getItemContent($path); //use the QtiParser to transform the QTI XML into an assoc array representation try { //load content $qtiParser = new QtiParser($content); //validate it $qtiParser->validate(); if (!$qtiParser->isValid()) { throw new common_Exception('Invalid QTI content : ' . $qtiParser->displayErrors(false)); } //parse $qtiItem = $qtiParser->load(); //then build the ItemPack from the parsed data if (!is_null($qtiItem)) { $itemPack = new ItemPack(self::$itemType, $qtiItem->toArray()); $itemPack->setAssetEncoders($this->getAssetEncoders()); $assetParser = new AssetParser($qtiItem, $path); $assetParser->setDeepParsing($this->isNestedResourcesInclusion()); foreach ($assetParser->extract($itemPack) as $type => $assets) { $itemPack->setAssets($type, $assets, $path); } } } catch (common_Exception $e) { throw new common_Exception('Unable to pack item ' . $item->getUri() . ' : ' . $e->getMessage()); } return $itemPack; }
/** * test if alternative QTI profiles are managed correctly during parsing */ public function testParseAlternativeProfile() { $file = dirname(__FILE__) . '/samples/xml/qtiv2p1/alternativeProfiles/apip001.xml'; $qtiParser = new Parser($file); $qtiParser->validate(); if (!$qtiParser->isValid()) { $this->fail($qtiParser->displayErrors()); } $this->assertTrue($qtiParser->isValid()); $item = $qtiParser->load(); $this->assertInstanceOf('\\oat\\taoQtiItem\\model\\qti\\Item', $item); $xml = simplexml_load_string($item->toXML()); $this->assertEquals('http://www.imsglobal.org/xsd/apip/apipv1p0/qtiitem/imsqti_v2p1', $xml->getNamespaces()['']); $this->assertNotNull($xml->apipAccessibility); }
/** * packItem implementation for QTI * @inheritdoc * @see {@link ItemPacker} * @throws InvalidArgumentException * @throws common_Exception */ public function packItem(core_kernel_classes_Resource $item, $lang, Directory $directory) { //use the QtiParser to transform the QTI XML into an assoc array representation $content = $this->getXmlByItem($item, $lang); //load content $qtiParser = new QtiParser($content); //validate it $qtiParser->validate(); if (!$qtiParser->isValid()) { throw new common_Exception('Invalid QTI content : ' . $qtiParser->displayErrors(false)); } //parse $qtiItem = $qtiParser->load(); return $this->packQtiItem($item, $lang, $qtiItem, $directory); }
/** * test the building and exporting out the items * @dataProvider itemProvider */ public function testToQTI($file) { $qtiParser = new Parser($file); $item = $qtiParser->load(); //test if content has been exported $qti = $item->toXML(); $this->assertFalse(empty($qti)); //test if it's a valid QTI file $tmpFile = $this->createFile('', uniqid('qti_', true) . '.xml'); file_put_contents($tmpFile, $qti); $this->assertTrue(file_exists($tmpFile)); $parserValidator = new Parser($tmpFile); $parserValidator->validate(); if (!$parserValidator->isValid()) { $this->fail($file . ' output invalid :' . $parserValidator->displayErrors() . ' -> ' . $qti); } }
public function testFileParsingQtiPic() { $files = glob(dirname(__FILE__) . '/samples/xml/qtiv2p1/pic/*.xml'); //check if samples are loaded foreach ($files as $file) { $qtiParser = new Parser($file); $qtiParser->validate(); if (!$qtiParser->isValid()) { echo $qtiParser->displayErrors(); } $item = $qtiParser->load(); $this->assertInstanceOf('\\oat\\taoQtiItem\\model\\qti\\Item', $item); } }
/** * Load a QTI item from a qti file in parameter. * * @access public * @author Somsack Sipasseuth, <*****@*****.**> * @param string file * @return oat\taoQtiItem\model\qti\Item */ public function loadItemFromFile($file) { $returnValue = null; if (is_string($file) && !empty($file)) { //validate the file to import try { $qtiParser = new Parser($file); $qtiParser->validate(); if (!$qtiParser->isValid()) { throw new ParsingException($qtiParser->displayErrors()); } $returnValue = $qtiParser->load(); } catch (ParsingException $pe) { throw new ParsingException($pe->getMessage()); } catch (Exception $e) { throw new Exception("Unable to load file {$file} caused by {$e->getMessage()}"); } } return $returnValue; }