private static function _setDocId(&$subdoc, &$parentNode, $id, &$docIdXpath, $curLevel = 0) {
        if ($parentNode->nodeName == $docIdXpath[$curLevel]) {
            if ($curLevel == count($docIdXpath) - 1) {
                // remove all sub-nodes
                $curChild = $parentNode->firstChild;
                while ($curChild) {
                    $nextChild = $curChild->nextSibling;
                    $parentNode->removeChild($curChild);
                    $curChild = $nextChild;
                }
                // set the ID
                if (!CPS_Request::isValidUTF8((string) $id))
                	throw new CPS_Exception(array(array('long_message' => 'Invalid UTF-8 encoding in document ID', 'code' => ERROR_CODE_INVALID_UTF8, 'level' => 'ERROR', 'source' => 'CPS_API')));
                $textNode = $subdoc->createTextNode($id);
                $parentNode->appendChild($textNode);
            } else {
                // traverse children
                $found = false;
                $curChild = $parentNode->firstChild;
                while ($curChild) {
                    if ($curChild->nodeName == $docIdXpath[$curLevel + 1]) {
                        CPS_Request::_setDocId($subdoc, $curChild, $id, $docIdXpath, $curLevel + 1);
                        $found = true;
                        break;
                    }
                    $curChild = $curChild->nextSibling;
                }
                if (!$found) {
                    $newNode = $subdoc->createElement($docIdXpath[$curLevel + 1]);
                    $parentNode->appendChild($newNode);
                    CPS_Request::_setDocId($subdoc, $newNode, $id, $docIdXpath, $curLevel + 1);
                }
            }
        } else {
            throw new CPS_Exception(array(array('long_message' => 'Document root xpath not matching document ID xpath', 'code' => ERROR_CODE_INVALID_XPATHS, 'level' => 'REJECTED', 'source' => 'CPS_API')));
        }
    }