foreach ($xhtxmldoc->xmd_select_elements('child') as $chEl) {
    $chId = $xhtxmldoc->attributes[$chEl]['identifier'];
    // no get_att yet...
    if ($after_last || ($before_first = $before_first && $chId != $id_range_first)) {
        $xhtxmldoc->xmd_remove_element($chEl);
        continue;
    }
    if (($mdt_rec = $mdStore->mds_get(BID . '.' . $chId)) === FALSE) {
        $mdt = $mdObj->mdo_generate_default_xml_metadata();
    } else {
        $mdt = $mdt_rec;
    }
    $xhtxmldocchild = new xmddoc(explode("\n", $mdt));
    !$xhtxmldocchild->error or give_up($chId . ': ' . $xhtxmldocchild->error);
    // make stuff below a parameter? copy some already in importmanifest?
    $xhtxmldoc->xmd_copy_foreign_child($xhtxmldocchild, $xhtxmldocchild->xmd_select_single_element('title'), $chEl);
    $xhtxmldoc->xmd_copy_foreign_child($xhtxmldocchild, $xhtxmldocchild->xmd_select_single_element('resource'), $chEl);
    $after_last = $after_last || $chId == $id_range_last;
}
$xhtDoc = define_htt(HTT . '.htt', $urlp, $_course['path']);
$xhtDoc->xht_xmldoc = $xhtxmldoc;
$xhtDoc->xht_param['mdt'] = $xhtxmldoc->xmd_xml();
// GENERATE OUTPUT ------------------------------------------------------------>
foreach (explode("\n", $xhtDoc->htt_array['HTTP']) as $httpXtra) {
    if ($httpXtra) {
        $httpHeadXtra[] = $httpXtra;
    }
}
$xhtDoc->xht_get_lang = 'get_lang';
function resource_for($e)
{
 function store_md_and_traverse_subitems($mfdocId, $level, $counter, $contextElem, $treeElem, $parentElem)
 {
     global $_user, $xht_doc, $mdStore, $mdObj, $sdisub, $charset;
     //  $contextElem -> @identifier, metadata/lom
     //  $treeElem ->    title, items
     $itemId = $xht_doc->xmd_value(ITEMID, $contextElem);
     if ($sdisub && $level == 1 && $sdisub != $itemId) {
         return;
     }
     //  <item level=... number=... identifier=...>:
     //      <title>...</title>
     //      <parent identifier=... /> <previous ... /> <next ... />
     //      <child identifier=... /> <child identifier=... /> ...
     //      <resource href=...>
     //          <file href=... /> <file href=... /> ...
     //      </resource>
     //      <metadata>...</metadata>
     //  </item>
     set_time_limit(30);
     // again 30 seconds from here on...
     $mddoc = new xmddoc('<item/>');
     // version, name ?
     $mddoc->xmd_set_attribute(0, 'level', $level, false);
     $mddoc->xmd_set_attribute(0, 'number', $counter, false);
     $mddoc->xmd_set_attribute(0, IDENTIF, $itemId, false);
     if ($level == 0) {
         $mddoc->xmd_set_attribute(0, 'created', date('Y/m/d H:i:s'), false);
         $mddoc->xmd_set_attribute(0, 'by', $_user['user_id'], false);
     }
     $mddoc->xmd_add_text_element(TITLE, $xht_doc->xmd_value(TITLE, $treeElem));
     if ($ppnId = $xht_doc->xmd_value(ITEMID, $parentElem)) {
         $mddoc->xmd_add_element('parent', 0, array(IDENTIF => $ppnId));
     }
     if ($ppnId = $xht_doc->xmd_value('-' . SUBIT, $treeElem)) {
         $mddoc->xmd_add_element('previous', 0, array(IDENTIF => $ppnId));
     }
     if ($ppnId = $xht_doc->xmd_value('+' . SUBIT, $treeElem)) {
         $mddoc->xmd_add_element('next', 0, array(IDENTIF => $ppnId));
     }
     if (($srcElem = resource_for($treeElem)) > 0) {
         // change stuff below to xmd_copy_foreign_child ?
         $resElem = $mddoc->xmd_add_element('resource', 0, array(HREF => $xht_doc->xmd_value(WEBF, $srcElem)));
         foreach ($xht_doc->xmd_select_elements(FILE, $srcElem) as $fileElem) {
             $mddoc->xmd_add_element(FILE, $resElem, array(HREF => $xht_doc->xmd_value(WEBF, $fileElem)));
         }
     }
     $mddoc->xmd_copy_foreign_child($xht_doc, $xht_doc->xmd_select_single_element('metadata', $contextElem));
     foreach ($xht_doc->xmd_select_elements(SUBITEM, $treeElem) as $subElem) {
         $mddoc->xmd_add_element('child', 0, array(IDENTIF => $xht_doc->xmd_value(ITEMID, $subElem)));
     }
     $mdt = $mddoc->xmd_xml();
     $xhtDoc = $mdObj->mdo_define_htt();
     $xhtDoc->xht_xmldoc = $mddoc;
     // $xhtDoc->xht_param['xxx'] = 'yyy';
     $mdStore->mds_put($eid = EID_TYPE . '.' . $mfdocId . '.' . $itemId, $mdt, 'mdxmltext', '?');
     $mdStore->mds_put($eid, $ixt = $xhtDoc->xht_fill_template('INDEXABLETEXT'), 'indexabletext');
     if ($level == 0) {
         $mdStore->mds_put(EID_TYPE . '.' . $mfdocId, $mdt, 'mdxmltext', '?');
         $mdStore->mds_put(EID_TYPE . '.' . $mfdocId, $ixt, 'indexabletext');
     }
     echo $level <= 1 ? '<br />' . $level . '/ ' : ' ', htmlspecialchars($itemId, ENT_QUOTES, $charset);
     flush();
     $loopctr = 0;
     foreach ($xht_doc->xmd_select_elements(SUBITEM, $treeElem) as $subElem) {
         store_md_and_traverse_subitems($mfdocId, $level + 1, ++$loopctr, $subElem, $subElem, $contextElem);
         // note: replacing this recursion by queue+loop makes it slower!
     }
 }
$testdoc->xmd_update('newtag/~', '');
showDoc("After update 'newtag/~', ''");
$keepdoc = $testdoc;
$wrongdoc = "<html>\n  <body>\n    <p>Text</p>\n    <p>More text" . "\n  </body>\n</html>";
$testdoc = new xmddoc(explode("\n", $wrongdoc));
showDoc('Xml doc with syntax error + error message', $wrongdoc . "\n\n" . $testdoc->error);
$xmlFile = 'imsmanifest_reload.xml';
$presXmlFileContents = @file_get_contents_n($xmlFile) or die('XML file  ' . htmlspecialchars($xmlFile) . ' is missing...');
showDoc('XML file to be parsed', $presXmlFileContents);
$testdoc = new xmddoc(explode("\n", $presXmlFileContents));
unset($presXmlFileContents);
if ($testdoc->error) {
    die($xmlFile . ':<br><br>' . $testdoc->error);
}
$testdoc->xmd_update_many('metadata/lom/general/title,metadata/lom/general/description', 'langstring/@lang', 'fr');
$testdoc->xmd_copy_foreign_child($keepdoc, $keepdoc->xmd_select_single_element('sometag[2]'));
showDoc('After parsing, and after changing 2* langstring/@lang to fr, ' . 'and after adding a foreign doc, reconstruction from memory');
showDoc('Element tagname of first metadata/lom/* element', $testdoc->name[$testdoc->xmd_select_single_element('metadata/lom/*')]);
showDoc('Element namespace URI of metadata/lom/*[2]', $testdoc->xmd_get_ns_uri($testdoc->xmd_select_single_element('metadata/lom/*[2]')));
showDoc('Number of metadata/lom/* elements', count($testdoc->xmd_select_elements('metadata/lom/*')));
showDoc('Number of resources/resource/file elements with @href', count($testdoc->xmd_select_elements_where_notempty('resources/resource/file', '@href')));
$elems = $testdoc->xmd_select_elements_where('resources/resource', 'file[1]/@href', 'three.html');
showDoc('Resource identifier where file[1]/@href is three.html', $testdoc->xmd_value('@identifier', $elems[0]));
$elems = $testdoc->xmd_select_elements_where('resources/resource', '@identifier', $testdoc->xmd_value('organizations/organization/item[2]/@identifierref'));
showDoc('Resource href for item[2]', $testdoc->xmd_value('@href', $elems[0]));
$stuff = '';
foreach (array('@identifier', 'metadata/schema', '*/*/*/*[1]/langstring', 'resources/resource[3]/@href', 'resources/resource[3]/file/@href', 'resources/resource[3]/@*', 'resources/resource[3]/-/@href', 'resources/resource[3]/+/@href', 'resources/resource[1]/-/@href', 'resources/../../../../../../../@identifier', '@*', 'resources/@*', 'organizations/organization/item[4]/title', 'organizations/organization/item[-2]/title', 'organizations/organization/item[4]/@*', 'organizations/organization/item[4]/@*item', 'organizations/organization/item[2]/+item/title', 'organizations/organization/item[2]/+/+/+/title', 'organizations/organization/item[2]/-item', 'organizations/organization/item[1]/-item', 'organizations/organization/item[1]/-', 'organizations/organization/item[1]/-/@.') as $path) {
    $stuff .= $path . ' => ' . $testdoc->xmd_value($path) . "\n";
}
showDoc('Values of: @identifier, metadata/schema, ... (see below)', $stuff);
function showHtml($path)