/** * Build a QTI_Item from a DOMElement, the root tag of which is root assessmentItem * * @param DOMElement $data * @return \oat\taoQtiItem\model\qti\Item * @throws InvalidArgumentException * @throws ParsingException * @throws UnsupportedQtiElement */ protected function buildItem(DOMElement $data) { //check on the root tag. $itemId = (string) $data->getAttribute('identifier'); common_Logger::i('Started parsing of QTI item' . (isset($itemId) ? ' ' . $itemId : ''), array('TAOITEMS')); //create the item instance $this->item = new Item($this->extractAttributes($data)); //load xml ns and schema locations $this->loadNamespaces(); $this->loadSchemaLocations($data); //load stylesheets $styleSheetNodes = $this->queryXPath("*[name(.) = 'stylesheet']", $data); foreach ($styleSheetNodes as $styleSheetNode) { $styleSheet = $this->buildStylesheet($styleSheetNode); $this->item->addStylesheet($styleSheet); } //extract the responses $responseNodes = $this->queryXPath("*[name(.) = 'responseDeclaration']", $data); foreach ($responseNodes as $responseNode) { $response = $this->buildResponseDeclaration($responseNode); if (!is_null($response)) { $this->item->addResponse($response); } } //extract outcome variables $outcomes = array(); $outComeNodes = $this->queryXPath("*[name(.) = 'outcomeDeclaration']", $data); foreach ($outComeNodes as $outComeNode) { $outcome = $this->buildOutcomeDeclaration($outComeNode); if (!is_null($outcome)) { $outcomes[] = $outcome; } } if (count($outcomes) > 0) { $this->item->setOutcomes($outcomes); } //extract modal feedbacks $feedbackNodes = $this->queryXPath("*[name(.) = 'modalFeedback']", $data); foreach ($feedbackNodes as $feedbackNode) { $modalFeedback = $this->buildFeedback($feedbackNode); if (!is_null($modalFeedback)) { $this->item->addModalFeedback($modalFeedback); } } //extract the item structure to separate the structural/style content to the item content $itemBodies = $this->queryXPath("*[name(.) = 'itemBody']", $data); // array with 1 or zero bodies if ($itemBodies === false) { $errors = libxml_get_errors(); if (count($errors) > 0) { $error = array_shift($errors); $errormsg = $error->message; } else { $errormsg = "without errormessage"; } throw new ParsingException('XML error(' . $errormsg . ') on itemBody read' . (isset($itemId) ? ' for item ' . $itemId : '')); } elseif ($itemBodies->length) { $this->parseContainerItemBody($itemBodies->item(0), $this->item->getBody()); $this->item->addClass($itemBodies->item(0)->getAttribute('class')); } //warning: extract the response processing at the latest to make oat\taoQtiItem\model\qti\response\TemplatesDriven::takeOverFrom() work $rpNodes = $this->queryXPath("*[name(.) = 'responseProcessing']", $data); if ($rpNodes->length === 0) { common_Logger::i('No responseProcessing found for QTI Item, setting empty custom', array('QTI', 'TAOITEMS')); $customrp = new Custom(array(), '<responseProcessing/>'); $this->item->setResponseProcessing($customrp); } else { $rpNode = $rpNodes->item(0); //the node should be alone $rProcessing = $this->buildResponseProcessing($rpNode, $this->item); if (!is_null($rProcessing)) { $this->item->setResponseProcessing($rProcessing); } } $this->buildApipAccessibility($data); return $this->item; }