Get template from some to-be-copied
        :class:`rtcclient.workitem.Workitem`

        The resulting XML document is returned as a :class:`string`, but if
        `template_name` (a string value) is specified,
        it is written there instead.

        :param copied_from: the to-be-copied
            :class:`rtcclient.workitem.Workitem` id (integer or
            equivalent string)
        :param template_name: the template file name
        :param template_folder: the folder to store template file
        :param keep: (default is False) If `True`, some of below parameters
            (which may not be included in some customized
            :class:`rtcclient.workitem.Workitem` type ) will remain
            unchangeable with the to-be-copied
            :class:`rtcclient.workitem.Workitem`.
            Otherwise for `False`.

                * teamArea (Team Area)
                * ownedBy (Owned By)
                * plannedFor(Planned For)
                * severity(Severity)
                * priority(Priority)
                * filedAgainst(Filed Against)
        :param encoding: (default is "UTF-8") coding format
        :return:

            * a :class:`string` object: if `template_name` is not specified
            * write the template to file `template_name`: if `template_name` is
              specified

def getTemplate(self, copied_from, template_name=None,
                    template_folder=None, keep=False, encoding="UTF-8"):
        """Get template from some to-be-copied
        :class:`rtcclient.workitem.Workitem`

        The resulting XML document is returned as a :class:`string`, but if
        `template_name` (a string value) is specified,
        it is written there instead.

        :param copied_from: the to-be-copied
            :class:`rtcclient.workitem.Workitem` id (integer or
            equivalent string)
        :param template_name: the template file name
        :param template_folder: the folder to store template file
        :param keep: (default is False) If `True`, some of below parameters
            (which may not be included in some customized
            :class:`rtcclient.workitem.Workitem` type ) will remain
            unchangeable with the to-be-copied
            :class:`rtcclient.workitem.Workitem`.
            Otherwise for `False`.

                * teamArea (Team Area)
                * ownedBy (Owned By)
                * plannedFor(Planned For)
                * severity(Severity)
                * priority(Priority)
                * filedAgainst(Filed Against)
        :param encoding: (default is "UTF-8") coding format
        :return:

            * a :class:`string` object: if `template_name` is not specified
            * write the template to file `template_name`: if `template_name` is
              specified
        """

        try:
            if isinstance(copied_from, bool) or isinstance(copied_from, float):
                raise ValueError()
            if isinstance(copied_from, six.string_types):
                copied_from = int(copied_from)
            if not isinstance(copied_from, int):
                raise ValueError()
        except ValueError:
            err_msg = "Please input a valid workitem id you want to copy from"
            self.log.error(err_msg)
            raise exception.BadValue(err_msg)

        self.log.info("Fetch the template from <Workitem %s> with [keep]=%s",
                      copied_from, keep)

        if template_folder is None:
            template_folder = self.searchpath

        # identify whether output to a file
        if template_name is not None:
            template_file_path = os.path.join(template_folder,
                                              template_name)
            output = open(template_file_path, "w")
        else:
            template_file_path = None
            output = None

        workitem_url = "/".join([self.url,
                                 "oslc/workitems/%s" % copied_from])
        resp = self.get(workitem_url,
                        verify=False,
                        proxies=self.rtc_obj.proxies,
                        headers=self.rtc_obj.headers)
        raw_data = xmltodict.parse(resp.content)

        # pre-adjust the template:
        # remove some attribute to avoid being overwritten, which will only be
        # generated when the workitem is created
        wk_raw_data = raw_data.get("oslc_cm:ChangeRequest")
        self._remove_long_fields(wk_raw_data)

        # Be cautious when you want to modify these fields
        # These fields have been tested as must-removed one
        remove_fields = ["@rdf:about",
                         "dc:created",
                         "dc:creator",
                         "dc:identifier",
                         "rtc_cm:contextId",
                         "rtc_cm:comments",
                         "rtc_cm:state",
                         "dc:type",
                         "rtc_cm:subscribers",
                         "dc:modified",
                         "rtc_cm:modifiedBy",
                         "rtc_cm:resolved",
                         "rtc_cm:resolvedBy",
                         "rtc_cm:resolution",
                         "rtc_cm:startDate",
                         "rtc_cm:timeSpent",
                         "rtc_cm:progressTracking",
                         "rtc_cm:projectArea",
                         "oslc_cm:relatedChangeManagement",
                         "oslc_cm:trackedWorkItem",
                         "oslc_cm:tracksWorkItem",
                         "rtc_cm:timeSheet",
                         "oslc_pl:schedule"]

        for remove_field in remove_fields:
            try:
                wk_raw_data.pop(remove_field)
                self.log.debug("Successfully remove field [%s] from the "
                               "template originated from <Workitem %s>",
                               remove_field,
                               copied_from)
            except:
                self.log.warning("No field named [%s] in this template "
                                 "from <Workitem %s>", remove_field,
                                 copied_from)
                continue

        wk_raw_data["dc:description"] = "{{ description }}"
        wk_raw_data["dc:title"] = "{{ title }}"

        if keep:
            if template_file_path:
                self.log.info("Writing the template to file %s",
                              template_file_path)
            return xmltodict.unparse(raw_data, output=output,
                                     encoding=encoding,
                                     pretty=True)

        replace_fields = [("rtc_cm:teamArea", "{{ teamArea }}"),
                          ("rtc_cm:ownedBy", "{{ ownedBy }}"),
                          ("rtc_cm:plannedFor", "{{ plannedFor }}"),
                          ("rtc_cm:foundIn", "{{ foundIn }}"),
                          ("oslc_cm:severity", "{{ severity }}"),
                          ("oslc_cm:priority", "{{ priority }}"),
                          ("rtc_cm:filedAgainst", "{{ filedAgainst }}")]
        for field in replace_fields:
            try:
                wk_raw_data[field[0]]["@rdf:resource"] = field[1]
                self.log.debug("Successfully replace field [%s] with [%s]",
                               field[0], field[1])
            except:
                self.log.warning("Cannot replace field [%s]", field[0])
                continue

        if template_file_path:
            self.log.info("Writing the template to file %s",
                          template_file_path)

        return xmltodict.unparse(raw_data, output=output,
                                 encoding=encoding,
                                 pretty=True)