<?php $dom = new DomDocument(); $frag = $dom->createDocumentFragment(); $frag->appendChild(new DOMElement('root')); $dom->appendChild($frag); $root = $dom->documentElement; $frag->appendChild(new DOMElement('first')); $root->appendChild($frag); $frag->appendChild(new DOMElement('second')); $root->appendChild($frag); $node = $dom->createElement('newfirst'); $frag->appendChild($node); $root->replaceChild($frag, $root->firstChild); unset($frag); $frag = $dom->createDocumentFragment(); $frag->appendChild(new DOMElement('newsecond')); $root->replaceChild($frag, $root->lastChild); $node = $frag->appendChild(new DOMElement('fourth')); $root->insertBefore($frag, NULL); $frag->appendChild(new DOMElement('third')); $node = $root->insertBefore($frag, $node); $frag->appendChild(new DOMElement('start')); $root->insertBefore($frag, $root->firstChild); $frag->appendChild(new DOMElement('newthird')); $root->replaceChild($frag, $node); $frag->appendChild(new DOMElement('newfourth')); $root->replaceChild($frag, $root->lastChild); $frag->appendChild(new DOMElement('first')); $root->replaceChild($frag, $root->firstChild->nextSibling); $root->removeChild($root->firstChild);
private function _makeOpfDoc($xml = null) { $opf = new DomDocument('1.0', 'utf-8'); $opf->preserveWhiteSpace = FALSE; $opf->validateOnParse = true; if ($xml == null) { $xml = '<?xml version="1.0" encoding="UTF-8" ?><package version="' . $this->packageVersion . '" unique-identifier="' . $this->uniqIDscheme . '" xmlns="' . $this->opfNS . '"></package>'; $opf->loadXML($xml); $package = $opf->getElementsByTagName('package')->item(0); // multiple namespaces on an element require us to use document fragments from strings $frag = $opf->createDocumentFragment(); if (!$frag->appendXML('<metadata xmlns:dc="' . $this->dcNS . '" xmlns:opf="' . $this->opfNS . '" />')) { throw new Exception('could not create metadata fragment' . "\n"); } $this->opf_metadataNode = $package->appendChild($frag); $this->opf_manifestNode = $package->appendChild($opf->createElement('manifest')); $this->opf_spineNode = $package->appendChild($opf->createElement('spine')); } else { // fix a typo bug that infected many BG packages (we // do it this way because php wont let us modify the // xmlns attribute after parsing: $xml = str_replace('http://www.idpf.og/2007/opf', 'http://www.idpf.org/2007/opf', $xml); @$opf->loadXML($xml); $package = $opf->getElementsByTagName('package')->item(0); if (!is_object($package)) { //error_log('no package element found'); throw new Exception('package element missing or malformed'); } if ($package->hasAttribute('xmlns')) { if ($package->getAttribute('xmlns') != $this->opfNS) { // correct this // this won't work due to a bug in PHP, but whatever // maybe someday some asshole will fix it. $package->setAttribute('xmlns', $this->opfNS); // should maybe save but holding off on that //$opf->formatOutput = TRUE; //$opf->save($this->packagepath . '/'.$this->opfpath); } else { //error_log($package->getAttribute('xmlns')); } } else { //error_log('package has no xmlns attribute!!'); } if ($package->getElementsByTagName('dc-metadata')->length > 0) { // old-style meta $this->opf_metadataNode = $package->getElementsByTagName('dc-metadata')->item(0); } else { $this->opf_metadataNode = $package->getElementsByTagName('metadata')->item(0); } $this->opf_manifestNode = $package->getElementsByTagName('manifest')->item(0); $this->uniqIDscheme = $package->getAttribute('unique-identifier'); if (!$this->uniqIDscheme) { $this->uniqIDscheme = 'PrimaryID'; $package->setAttribute('unique-identifier', $this->uniqIDscheme); } if (!$opf->getElementsByTagName('identifier')->item(0)) { // no identifiers at all!! $newval = 'urn:uuid:' . uuidGen::generateUuid(); $id = $this->opf_metadataNode->appendChild($opf->createElement('identifier')); $id->appendChild($opf->createTextNode($newval)); $id->setAttribute('id', $this->uniqIDscheme); $this->uniqIDval = $newval; } foreach ($opf->getElementsByTagName('identifier') as $id) { if ($id->getAttribute('id') == $this->uniqIDscheme) { $this->uniqIDval = trim($id->nodeValue); } } if (!strlen($this->uniqIDval) > 1) { throw new Exception("EPUB file must have a globally unique identifier such as a GUID."); } $this->opf_spineNode = $package->getElementsByTagName('spine')->item(0); if (!$this->opf_metadataNode || !$this->opf_manifestNode || !$this->opf_spineNode) { throw new Exception('this opf structure is incomplete'); } } $this->opfXP = new DomXpath($opf); $this->opfXP->registerNamespace("opfns", $this->opfNS); $this->opfXP->registerNamespace("dc", $this->dcNS); return $opf; }
echo "\n"; echo "t1 == ret: "; var_dump($t1 === $ret); $d = $xml->createElement("div"); $d->appendChild($t3 = $xml->createTextNode(" t3 ")); $d->appendChild($b = $xml->createElement("b")); $b->appendChild($xml->createElement("X")); $d->appendChild($t4 = $xml->createTextNode(" t4 ")); $d->appendChild($xml->createTextNode(" xxx ")); echo "\ndiv:\n"; print_node_r($d); echo "\nInsert t4 before t3:\n"; $ret = $d->insertBefore($t4, $t3); print_node_r($d); echo "\n"; $frag = $xml->createDocumentFragment(); $t5 = $frag->appendChild($xml->createTextNode(" t5 ")); $frag->appendChild($i = $xml->createElement("i")); $i->appendChild($xml->createTextNode(" frob ")); $frag->appendChild($xml->createTextNOde(" t6 ")); echo "\np:\n"; print_node_r($p); echo "\nFragment:\n"; print_node_r($frag); echo "\nAppending fragment to p:\n"; $p->appendChild($frag); print_node_r($p); echo "\nFragment:\n"; print_node_r($frag); echo "\ndiv:\n"; print_node_r($d);
/** * Filter the page html and look for an <a><img> element added by the chooser * or an <a> element added by the moodle file picker * * NOTE: Thumbnail html from the Chooser and a link from the old filepicker * are of the same form (see $_re_api1_public_urls). * A thumbnail link from the new repository filepicker plugin is * different (see $_re_api2_public_urls). * The latest version of the local lib and rich text editor plugins * use both a trusted and a regular embed url as the href value of * the thumbnail html (this is the preferred route going forward). * Both types of embed_urls will need a user to be authenticated * before they can view the embed. * * @param string $html * @param array $options * @return string */ public function filter($html, array $options = array()) { global $COURSE; $courseid = isset($COURSE->id) ? $COURSE->id : null; if (empty($html) || !is_string($html) || strpos($html, $this->_mcore_client->get_host()) === false) { return $html; } $dom = new DomDocument(); @$dom->loadHtml(mb_convert_encoding($html, 'HTML-ENTITIES', 'UTF-8')); $xpath = new DOMXPath($dom); foreach ($xpath->query('//a') as $node) { $href = $node->getAttribute('href'); if (empty($href)) { continue; } if ((bool) preg_match($this->_re_embed_url, $href)) { $newnode = $dom->createDocumentFragment(); $imgnode = $node->firstChild; if ($this->_mcore_client->has_lti_config() && !is_null($courseid)) { $href = $this->_generate_embed_url($href, $courseid); } else { $href = htmlspecialchars($href); } extract($this->_get_image_elem_dimensions($imgnode)); $html = $this->_get_iframe_embed_html($href, $width, $height); $newnode->appendXML($html); $node->parentNode->replaceChild($newnode, $node); } else { if ((bool) preg_match($this->_re_api1_public_urls, $href)) { $newnode = $dom->createDocumentFragment(); $imgnode = $node->firstChild; extract($this->_get_image_elem_dimensions($imgnode)); $html = $this->_get_embed_html_from_api1_public_url($href, $width, $height, $courseid); $newnode->appendXML($html); $node->parentNode->replaceChild($newnode, $node); } else { if ((bool) preg_match($this->_re_api2_public_urls, $href)) { $newnode = $dom->createDocumentFragment(); $width = $this->_default_thumb_width; $height = $this->_default_thumb_height; $html = $this->_get_embed_html_from_api2_public_url($href, $width, $height, $courseid); $newnode->appendXML($html); $node->parentNode->replaceChild($newnode, $node); } } } } return $dom->saveHTML(); }
function getSubjectDataAsXml($subjectLabel, Database $db) { if (empty($subjectLabel)) { throw new Exception("Empty subject label."); } //Retrieve the form data $result = $db->getSubjectData($subjectLabel); //Retrieve and decode the final data $finaldata = $db->getSubjectFinalData($subjectLabel); $skipped = 0; $xmlerrors = 0; $count = 0; //Register a new error handler to handle libxml specific errors $originalHandler = set_error_handler("libxml_error_handler"); //Create an XML document to store all the data (properly) $xmldoc = new DomDocument(); $xmldoc->loadXML('<result subject="' . $subjectLabel . '"/>'); //Create an XML document to store the final form data. This will be appended //to $xmldoc. $xmlFinal = $xmldoc->createDocumentFragment(); //Strip the <?xml .. tag $finalxmldata = str_replace('<?xml version="1.0"?>', '', $finaldata['data']); $xmlFinal->appendXML($finalxmldata); $nodeFinal = $xmldoc->createElement('final'); if ($xmlFinal->hasChildNodes()) { $nodeFinal->appendChild($xmlFinal); } $locked = 0; if ($finaldata['locked'] > 0) { $locked = $finaldata['locked']; } $nodeFinal->setAttribute('locked', $locked); //Insert the <final> element into the main XML document. $xmldoc->documentElement->appendChild($nodeFinal); /* Loop through all the sessions and append the data */ $lastSessionId = null; $xmlSession = null; //Get all the elements to construct a valid XML file foreach ($result as $row) { //Element doesn't conform to our schema arch? skip it. if (empty($row['schemaName'])) { $skipped++; continue; } $sessionId = $row['fkSessionID']; $schema = $row['schemaName']; $sessionLabel = $row['label']; $dateSessionCreated = $row['dateSessionCreated']; $subjectLabel = $row['subjectLabel']; $owner = $row['username']; $formId = $row['formID']; //Test data integrity try { $xmlForm = new DomDocument(); if (!$xmlForm->loadXML($row['data'])) { throw new Exception("Invalid XML data: Session " . $sessionLabel); } //Insert metadata as attributes of the <form> element $xmlForm->documentElement->setAttribute('id', $formId); $xmlForm->documentElement->setAttribute('schema', $schema); } catch (Exception $e) { //Keep track of errors $xmlerrors++; $skipped++; continue; } //Should we start a new session? if ($lastSessionId != $sessionId) { $count++; //Create a <session id='foo'/> element and append it to the document $nodeSession = $xmldoc->createElement('session'); $nodeSession->setAttribute('id', $sessionLabel); $nodeSession->setAttribute('owner', $owner); $nodeSession->setAttribute('date', $dateSessionCreated); //Insert the <session> element into the xml document $xmlSession = $xmldoc->documentElement->appendChild($nodeSession); } //Copy the data document as a child element of the sesssion $datanode = $xmldoc->importNode($xmlForm->documentElement, true); $nodeSession->appendChild($datanode); $lastSessionId = $sessionId; } //xmldoc contains the result organized as a list of sessions with form data $xmldoc->documentElement->setAttribute('total', $count); //Restore the original error handler if (!empty($originalHandler)) { set_error_handler($originalHandler); } //print $xmldoc->saveXML(); return $xmldoc; }
/** * Filter the page html and look for an <a><img> element added by the chooser * or an <a> element added by the moodle file picker * * * @param string $html * @param array $options * @return string */ public function filter($html, array $options = array()) { global $COURSE; $courseid = isset($COURSE->id) ? $COURSE->id : null; if (empty($html) || !is_string($html) || strpos($html, $this->_binumi_client->get_host()) === false) { return $html; } $dom = new DomDocument(); $sanitized_html = mb_convert_encoding($html, 'HTML-ENTITIES', 'UTF-8'); if (defined('LIBXML_HTML_NOIMPLIED') && defined('LIBXML_HTML_NODEFDTD')) { @$dom->loadHtml($sanitized_html, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD); } else { @$dom->loadHtml($sanitized_html); } $xpath = new DOMXPath($dom); foreach ($xpath->query('//a') as $node) { $href = $node->getAttribute('href'); $class = $node->getAttribute('class'); if (empty($href)) { continue; } if ($class != 'binumi-embed') { continue; } if ((bool) preg_match($this->_re_embed_url, $href)) { $newnode = $dom->createDocumentFragment(); $imgnode = $node->firstChild; $href = htmlspecialchars($href); extract($this->_get_image_elem_dimensions($imgnode)); $html = $this->_get_iframe_embed_html($href, $width, $height); $newnode->appendXML($html); $node->parentNode->replaceChild($newnode, $node); } } return $dom->saveHTML(); }
/** * Helper to inject the needed exslt function nodes in an XSL Stylesheet * * @param \DomDocument $stylesheet Stylesheet to inject the wrapper code into * @param String $key Instance hash used for mapping in fXSLTProcessor * * @return void */ public function injectCallbackCode(\DomDocument $stylesheet, $key) { $root = $stylesheet->documentElement; $this->setStylesheetProperties($root); $frag = $stylesheet->createDocumentFragment(); $frag->appendXML("\n<!-- Injected by fXSLCallback - START -->\n"); $rfo = new \ReflectionObject($this->object); $methods = $rfo->getMethods(\ReflectionMethod::IS_PUBLIC & ~\ReflectionMethod::IS_STATIC); if (!empty($methods)) { $this->registerMethods($frag, $key, $methods); } $frag->appendXML("\n<!-- Injected by fXSLCallback - END -->\n"); $root->appendChild($frag); }
protected function produceAtom($feedArray) { // Atom 1.0 $doc = new DomDocument('1.0', 'utf-8'); $feed = $doc->createElement('feed'); $feed->setAttribute('xmlns:itunes', 'http://www.itunes.com/dtds/podcast-1.0.dtd'); $feed->setAttribute('xmlns', 'http://www.w3.org/2005/Atom'); $feed->setAttribute('xml:lang', $feedArray['language']); $doc->appendChild($feed); $title = $doc->createElement('title', $feedArray['title']); $title->setAttribute('type', 'text'); $subtitle = $doc->createElement('subtitle', $feedArray['description']); $subtitle->setAttribute('type', 'text'); $updated = $doc->createElement('updated', date('Y-m-d\\TH:i:sP')); $generator = $doc->createElement('generator', ProjectConfiguration::getApplicationName() . ' Feed Module'); $link_alternate = $doc->createElement('link'); $link_alternate->setAttribute('rel', 'alternate'); $link_alternate->setAttribute('type', 'text/html'); $link_alternate->setAttribute('href', $feedArray['link']); $link_self = $doc->createElement('link'); $link_self->setAttribute('rel', 'self'); $link_self->setAttribute('type', 'application/atom+xml'); $link_self->setAttribute('href', $feedArray['atom_link']); $id = $doc->createElement('id', $feedArray['link']); $author = $doc->createElement('author'); $a_name = $doc->createElement('name', ProjectConfiguration::getApplicationName()); $a_email = $doc->createElement('email', ProjectConfiguration::getApplicationEmailAddress()); $a_uri = $doc->createElement('uri', $this->getController()->genUrl('@homepage', true)); $author->appendChild($a_name); $author->appendChild($a_email); $author->appendChild($a_uri); $feed->appendChild($title); $feed->appendChild($subtitle); $feed->appendChild($updated); $feed->appendChild($generator); $feed->appendChild($link_alternate); $feed->appendChild($link_self); $feed->appendChild($id); $feed->appendChild($author); $itunes_explicit = $doc->createElement('itunes:explicit', $feedArray["is_nsfw"]); $itunes_summary = $doc->createElement('itunes:summary', substr($feedArray['description'], 0, 3999)); $itunes_category = $doc->createElement('itunes:category'); $itunes_category->setAttribute('text', 'Technology'); $itunes_subcategory = $doc->createElement('itunes:category'); $itunes_subcategory->setAttribute('text', 'Podcasting'); $itunes_category->appendChild($itunes_subcategory); // Including the itunes:owner messes with the feed by overriding the title in iTunes. $feed->appendChild($itunes_explicit); $feed->appendChild($itunes_summary); $feed->appendChild($itunes_category); foreach ($feedArray['entries'] as $entry) { $fentry = $doc->createElement('entry'); //$fentry->setAttribute('xmlns:xhtml', 'http://www.w3.org/1999/xhtml'); $e_title = $doc->createElement('title'); $e_title->setAttribute('type', 'html'); $cdata_title = $doc->createCDATASection($entry['title']); $e_title->appendChild($cdata_title); $thumbnail_tag = $entry['thumbnail'] ? '<p><img src="' . $entry['thumbnail'] . '"/></p>' : ''; $e_summary = $doc->createElement('summary'); $e_summary->setAttribute('type', 'html'); $cdata_summary = $doc->createCDATASection($thumbnail_tag . substr($entry['description'], 0, 500)); $e_summary->appendChild($cdata_summary); $e_published = $doc->createElement('published', date('Y-m-d\\TH:i:sP', $entry['released'])); $e_updated = $doc->createElement('updated', date('Y-m-d\\TH:i:sP', $entry['modified'] > $entry['released'] ? $entry['modified'] : $entry['released'])); $e_link = $doc->createElement('link'); $e_link->setAttribute('rel', 'alternate'); $e_link->setAttribute('type', 'text/html'); $e_link->setAttribute('href', $entry['link']); $e_id = $doc->createElement('id', $entry['link']); $e_author = $doc->createElement('author'); $ea_name = $doc->createElement('name', $entry['author']['name']); $e_author->appendChild($ea_name); $e_enclosure = $doc->createElement('link'); $e_enclosure->setAttribute('rel', 'enclosure'); $audio_info = $this->getRemoteInfo($entry['audio_location']); $e_enclosure->setAttribute('type', $audio_info['type']); $e_enclosure->setAttribute('href', $entry['audio_location']); $e_enclosure->setAttribute('length', $audio_info['length']); $e_enclosure->setAttribute('title', 'Audio'); $e_content = $doc->createElement('content'); //$e_content->setAttribute('xmlns:xhtml', // 'http://www.w3.org/1999/xhtml'); $e_content->setAttribute('type', 'xhtml'); $fragment = $doc->createDocumentFragment(); $fragment->appendXML($thumbnail_tag . $entry['content']); $e_div = $doc->createElement('div'); $e_div->setAttribute('xmlns', 'http://www.w3.org/1999/xhtml'); $e_div->appendChild($fragment); $e_content->appendChild($e_div); if ($entry['reddit_post_url']) { $e_comments = $doc->createElement('link'); $e_comments->setAttribute('rel', 'replies'); $e_comments->setAttribute('type', 'text/html'); $e_comments->setAttribute('href', $entry['reddit_post_url']); } $fentry->appendChild($e_title); $fentry->appendChild($e_summary); $fentry->appendChild($e_published); $fentry->appendChild($e_updated); $fentry->appendChild($e_link); $fentry->appendChild($e_id); $fentry->appendChild($e_author); $fentry->appendChild($e_enclosure); $fentry->appendChild($e_content); $i_itunes_author = $doc->createElement('itunes:author', $entry['author']['name']); $i_itunes_summary = $doc->createElement('itunes:summary', substr(strip_tags($entry['description']), 0, 3999)); $i_itunes_explicit = $doc->createElement('itunes:explicit', $entry['is_nsfw']); $fentry->appendChild($i_itunes_author); $fentry->appendChild($i_itunes_summary); $fentry->appendChild($i_itunes_explicit); $feed->appendChild($fentry); } $doc->formatOutput = true; $doc->preserveWhitespace = false; return $doc->saveXML(); }
/** * Returns HTML string of an HTML document listing all the given files */ function proofsheet_create_html($files) { $html_document = new DomDocument(); $html_html = $html_document->createElement('html'); $html_document->appendChild($html_html); $html_head = $html_document->createElement('head'); $html_html->appendChild($html_head); $html_body = $html_document->createElement('body'); $html_html->appendChild($html_body); global $css; $frag = $html_document->createDocumentFragment(); $frag->appendXML($css); $html_head->appendChild($frag); foreach ($files as $file) { proofsheet_add_file_to_html($html_body, $file); } $html = $html_document->saveXML(); return $html; }
/** * addWaypoints * @return void */ public function addWaypoints() { $xml = new \DOMDocument(); $xml->loadXML($this->gpx); $waypoints = $xml->getElementsByTagName('wpt'); $dom = new \DomDocument(); $dom->loadHTML($this->html); $finder = new \DomXPath($dom); foreach ($waypoints as $waypoint) { $long_description = $waypoint->getElementsByTagNameNS('http://www.groundspeak.com/cache/1/0/1', 'long_description'); if (empty($long_description->length)) { continue; } if (!preg_match('#<p>Additional [Hidden\\s]+?Waypoints</p>#i', $long_description->item(0)->nodeValue, $matches, PREG_OFFSET_CAPTURE)) { continue; } $data = substr($long_description->item(0)->nodeValue, $matches[0][1] + strlen($matches[0][0])); if (!$data) { continue; } $details_waypoints = explode('<br />', $data); array_pop($details_waypoints); $details_waypoints = array_chunk($details_waypoints, 3); $gccode = $waypoint->getElementsByTagName('name')->item(0)->nodeValue; $nodes = $finder->query("//div[@data-cache-id='" . $gccode . "']//*[@class='cacheWaypoints']"); $frag = $dom->createDocumentFragment(); $frag->appendXML('<p>Waypoints</p>' . "\n"); if (!empty($nodes->length)) { $nodes->item(0)->appendChild($frag); } foreach ($details_waypoints as $wpt_data) { $title = preg_replace('/ GC[\\w]+/', ' ', $wpt_data[0]); $coordinates = ''; if ($wpt_data[1] !== '' && strpos($wpt_data[1], 'N/S') !== 0) { $coordinates = ' - ' . trim(html_entity_decode($wpt_data[1])); } $comment = $wpt_data[2]; $frag_wpt = $dom->createDocumentFragment(); $frag_wpt->appendXML('<![CDATA[<p><strong>' . $title . $coordinates . '</strong><br />' . $comment . "</p>\n]]>"); if (!empty($nodes->length)) { $nodes->item(0)->appendChild($frag_wpt); } } } $this->html = $dom->saveHtml(); }
/** * Highlights a keyword within a larger string. Won't insert the tags around the keyword if it's found within HTML tags. * see: http://stackoverflow.com/questions/4081372/highlight-keywords-in-a-paragraph * @param string $src String to search for the keyword text. * @param string $keyword String to search for and highlight. * @return string The original text with SPAN tags inserted around the keyword with a class attribute of 'highlight'. */ public static function highlightKeyword($src, $keyword) { $keyword = str_replace('*', '', $keyword); $src = "<div>{$src}</div>"; $dom = new DomDocument(); $dom->recover = true; @$dom->loadHtml($src); $xpath = new DomXpath($dom); $elements = $xpath->query('//*[contains(.,"' . $keyword . '")]'); foreach ($elements as $element) { foreach ($element->childNodes as $child) { if (!$child instanceof DomText) { continue; } $fragment = $dom->createDocumentFragment(); $text = $child->textContent; while (($pos = stripos($text, $keyword)) !== false) { $fragment->appendChild(new DomText(substr($text, 0, $pos))); $word = substr($text, $pos, strlen($keyword)); $highlight = $dom->createElement('span'); $highlight->appendChild(new DomText($word)); $highlight->setAttribute('class', 'searchterm'); $fragment->appendChild($highlight); $text = substr($text, $pos + strlen($keyword)); } if (!empty($text)) { $fragment->appendChild(new DomText($text)); } $element->replaceChild($fragment, $child); } } $str = $dom->saveXml($dom->getElementsByTagName('body')->item(0)->firstChild); return $str; }
protected function writeReal(MessageCollection $collection) { $mangler = $this->group->getMangler(); $template = new DomDocument('1.0'); $template->preserveWhiteSpace = false; $template->formatOutput = true; // Try to use the definition file as template $sourceLanguage = $this->group->getSourceLanguage(); $sourceFile = $this->group->getSourceFilePath($sourceLanguage); if (file_exists($sourceFile)) { $template->load($sourceFile); } else { // Else use standard template $template->load(__DIR__ . '/../data/xliff-template.xml'); } $list = $template->getElementsByTagName('body')->item(0); $list->nodeValue = null; /** @var TMessage $m */ foreach ($collection as $key => $m) { $key = $mangler->unmangle($key); $value = $m->translation(); $value = str_replace(TRANSLATE_FUZZY, '', $value); // @todo Support placeholder tags etc. $source = $template->createDocumentFragment(); $source->appendXML(htmlspecialchars($m->definition())); $target = $template->createDocumentFragment(); $target->appendXML(htmlspecialchars($value)); $sourceElement = $template->createElement('source'); $sourceElement->appendChild($source); $targetElement = $template->createElement('target'); $targetElement->appendChild($target); if ($m->getProperty('status') === 'fuzzy') { $targetElement->setAttribute('state', 'needs-l10n'); } if ($m->getProperty('status') === 'proofread') { $targetElement->setAttribute('state', 'signed-off'); } $transUnit = $template->createElement('trans-unit'); $transUnit->setAttribute('id', $key); $transUnit->appendChild($sourceElement); $transUnit->appendChild($targetElement); $list->appendChild($transUnit); } $template->encoding = 'UTF-8'; return $template->saveXML(); }