예제 #1
0
파일: ebrim.py 프로젝트: SNIMar-WP4/pycsw
    def write_record(self, result, esn, outputschema, queryables):
        ''' Return csw:SearchResults child as lxml.etree.Element '''

        identifier = util.getqattr(result, self.context.md_core_model['mappings']['pycsw:Identifier'])
        typename = util.getqattr(result, self.context.md_core_model['mappings']['pycsw:Typename'])

        if esn == 'full' and typename == 'rim:RegistryObject':
            # dump record as is and exit
            return etree.fromstring(util.getqattr(result, queryables['pycsw:XML']['dbcol']), self.context.parser)

        if typename == 'csw:Record':  # transform csw:Record -> rim:RegistryObject model mappings
            util.transform_mappings(queryables, self.repository['mappings']['csw:Record'])

        node = etree.Element(util.nspath_eval('rim:ExtrinsicObject', self.namespaces))
        node.attrib[util.nspath_eval('xsi:schemaLocation', self.context.namespaces)] = \
        '%s %s/csw/2.0.2/profiles/ebrim/1.0/csw-ebrim.xsd' % (self.namespaces['wrs'], self.ogc_schemas_base)

        node.attrib['id'] = identifier
        node.attrib['lid'] = identifier
        node.attrib['objectType'] = str(util.getqattr(result, self.context.md_core_model['mappings']['pycsw:Type']))
        node.attrib['status'] = 'urn:oasis:names:tc:ebxml-regrep:StatusType:Submitted'

        etree.SubElement(node, util.nspath_eval('rim:VersionInfo', self.namespaces), versionName='')

        if esn in ['summary', 'full']:
            etree.SubElement(node, util.nspath_eval('rim:ExternalIdentifier', self.namespaces), value=identifier, identificationScheme='foo', registryObject=str(util.getqattr(result, self.context.md_core_model['mappings']['pycsw:Relation'])), id=identifier)

            name = etree.SubElement(node, util.nspath_eval('rim:Name', self.namespaces))
            etree.SubElement(name, util.nspath_eval('rim:LocalizedString', self.namespaces), value=unicode(util.getqattr(result, self.context.md_core_model['mappings']['pycsw:Title'])))

            description = etree.SubElement(node, util.nspath_eval('rim:Description', self.namespaces))
            etree.SubElement(description, util.nspath_eval('rim:LocalizedString', self.namespaces), value=unicode(util.getqattr(result, self.context.md_core_model['mappings']['pycsw:Abstract'])))

            val = util.getqattr(result, self.context.md_core_model['mappings']['pycsw:BoundingBox'])
            bboxel = write_boundingbox(val, self.context.namespaces)

            if bboxel is not None:
                bboxslot = etree.SubElement(node, util.nspath_eval('rim:Slot', self.namespaces),
                slotType='urn:ogc:def:dataType:ISO-19107:2003:GM_Envelope')

                valuelist = etree.SubElement(bboxslot, util.nspath_eval('rim:ValueList', self.namespaces))
                value = etree.SubElement(valuelist, util.nspath_eval('rim:Value', self.namespaces))
                value.append(bboxel)

            rkeywords = util.getqattr(result, self.context.md_core_model['mappings']['pycsw:Keywords'])
            if rkeywords is not None:
                subjectslot = etree.SubElement(node, util.nspath_eval('rim:Slot', self.namespaces),
                name='http://purl.org/dc/elements/1.1/subject')
                valuelist = etree.SubElement(subjectslot, util.nspath_eval('rim:ValueList', self.namespaces))
                for keyword in rkeywords.split(','):
                    etree.SubElement(valuelist,
                    util.nspath_eval('rim:Value', self.namespaces)).text = keyword

        return node
예제 #2
0
def test_transform_mappings():
    queryables = {
        "q1": {"xpath": "p1", "dbcol": "col1"},
        "q2": {"xpath": "p2", "dbcol": "col2"},
    }
    typename = {"q2": "q1"}
    duplicate_queryables = queryables.copy()
    duplicate_typename = typename.copy()
    util.transform_mappings(duplicate_queryables, duplicate_typename)
    assert duplicate_queryables["q1"]["xpath"] == queryables["q2"]["xpath"]
    assert duplicate_queryables["q1"]["dbcol"] == queryables["q2"]["dbcol"]
예제 #3
0
def test_transform_mappings():
    queryables = {
        "q1": {"xpath": "p1", "dbcol": "col1"},
        "q2": {"xpath": "p2", "dbcol": "col2"},
    }
    typename = {"q2": "q1"}
    duplicate_queryables = queryables.copy()
    duplicate_typename = typename.copy()
    util.transform_mappings(duplicate_queryables, duplicate_typename)
    assert duplicate_queryables["q1"]["xpath"] == queryables["q2"]["xpath"]
    assert duplicate_queryables["q1"]["dbcol"] == queryables["q2"]["dbcol"]
예제 #4
0
    def write_record(self, result, esn, outputschema, queryables):
        ''' Return csw:SearchResults child as lxml.etree.Element '''

        identifier = util.getqattr(
            result, self.context.md_core_model['mappings']['pycsw:Identifier'])
        typename = util.getqattr(
            result, self.context.md_core_model['mappings']['pycsw:Typename'])

        if esn == 'full' and typename == 'rim:RegistryObject':
            # dump record as is and exit
            return etree.fromstring(
                util.getqattr(result, queryables['pycsw:XML']['dbcol']),
                self.context.parser)

        if typename == 'csw:Record':  # transform csw:Record -> rim:RegistryObject model mappings
            util.transform_mappings(queryables,
                                    self.repository['mappings']['csw:Record'])

        node = etree.Element(
            util.nspath_eval('rim:ExtrinsicObject', self.namespaces))
        node.attrib[util.nspath_eval('xsi:schemaLocation', self.context.namespaces)] = \
        '%s %s/csw/2.0.2/profiles/ebrim/1.0/csw-ebrim.xsd' % (self.namespaces['wrs'], self.ogc_schemas_base)

        node.attrib['id'] = identifier
        node.attrib['lid'] = identifier
        node.attrib['objectType'] = str(
            util.getqattr(
                result, self.context.md_core_model['mappings']['pycsw:Type']))
        node.attrib[
            'status'] = 'urn:oasis:names:tc:ebxml-regrep:StatusType:Submitted'

        etree.SubElement(node,
                         util.nspath_eval('rim:VersionInfo', self.namespaces),
                         versionName='')

        if esn in ['summary', 'full']:
            etree.SubElement(node,
                             util.nspath_eval('rim:ExternalIdentifier',
                                              self.namespaces),
                             value=identifier,
                             identificationScheme='foo',
                             registryObject=str(
                                 util.getqattr(
                                     result,
                                     self.context.md_core_model['mappings']
                                     ['pycsw:Relation'])),
                             id=identifier)

            name = etree.SubElement(
                node, util.nspath_eval('rim:Name', self.namespaces))
            etree.SubElement(name,
                             util.nspath_eval('rim:LocalizedString',
                                              self.namespaces),
                             value=text_type(
                                 util.getqattr(
                                     result,
                                     self.context.md_core_model['mappings']
                                     ['pycsw:Title'])))

            description = etree.SubElement(
                node, util.nspath_eval('rim:Description', self.namespaces))
            etree.SubElement(description,
                             util.nspath_eval('rim:LocalizedString',
                                              self.namespaces),
                             value=text_type(
                                 util.getqattr(
                                     result,
                                     self.context.md_core_model['mappings']
                                     ['pycsw:Abstract'])))

            val = util.getqattr(
                result,
                self.context.md_core_model['mappings']['pycsw:BoundingBox'])
            bboxel = write_boundingbox(val, self.context.namespaces)

            if bboxel is not None:
                bboxslot = etree.SubElement(
                    node,
                    util.nspath_eval('rim:Slot', self.namespaces),
                    slotType='urn:ogc:def:dataType:ISO-19107:2003:GM_Envelope')

                valuelist = etree.SubElement(
                    bboxslot, util.nspath_eval('rim:ValueList',
                                               self.namespaces))
                value = etree.SubElement(
                    valuelist, util.nspath_eval('rim:Value', self.namespaces))
                value.append(bboxel)

            rkeywords = util.getqattr(
                result,
                self.context.md_core_model['mappings']['pycsw:Keywords'])
            if rkeywords is not None:
                subjectslot = etree.SubElement(
                    node,
                    util.nspath_eval('rim:Slot', self.namespaces),
                    name='http://purl.org/dc/elements/1.1/subject')
                valuelist = etree.SubElement(
                    subjectslot,
                    util.nspath_eval('rim:ValueList', self.namespaces))
                for keyword in rkeywords.split(','):
                    etree.SubElement(
                        valuelist,
                        util.nspath_eval('rim:Value',
                                         self.namespaces)).text = keyword

        return node
예제 #5
0
파일: apiso.py 프로젝트: SNIMar-WP4/pycsw
    def write_record(self, result, esn, outputschema, queryables, caps=None):
        ''' Return csw:SearchResults child as lxml.etree.Element '''
        typename = util.getqattr(result, self.context.md_core_model['mappings']['pycsw:Typename'])
        is_iso_anyway = False

        xml_blob = util.getqattr(result, self.context.md_core_model['mappings']['pycsw:XML'])
        if caps is None and xml_blob is not None and xml_blob.startswith('<gmd:MD_Metadata'):
            is_iso_anyway = True

        if (esn == 'full' and (typename == 'gmd:MD_Metadata' or is_iso_anyway)):
            # dump record as is and exit
            return etree.fromstring(xml_blob, self.context.parser)

        if typename == 'csw:Record':  # transform csw:Record -> gmd:MD_Metadata model mappings
            util.transform_mappings(queryables, self.repository['mappings']['csw:Record'])

        node = etree.Element(util.nspath_eval('gmd:MD_Metadata', self.namespaces))
        node.attrib[util.nspath_eval('xsi:schemaLocation', self.context.namespaces)] = \
        '%s %s/csw/2.0.2/profiles/apiso/1.0.0/apiso.xsd' % (self.namespace, self.ogc_schemas_base)

        # identifier
        idval = util.getqattr(result, self.context.md_core_model['mappings']['pycsw:Identifier'])

        identifier = etree.SubElement(node, util.nspath_eval('gmd:fileIdentifier', self.namespaces))
        etree.SubElement(identifier, util.nspath_eval('gco:CharacterString', self.namespaces)).text = idval

        if esn in ['summary', 'full']:
            # language
            val = util.getqattr(result, queryables['apiso:Language']['dbcol'])

            lang = etree.SubElement(node, util.nspath_eval('gmd:language', self.namespaces))
            etree.SubElement(lang, util.nspath_eval('gco:CharacterString', self.namespaces)).text = val

        # hierarchyLevel
        mtype = util.getqattr(result, queryables['apiso:Type']['dbcol']) or None

        if mtype is not None: 
            if mtype == 'http://purl.org/dc/dcmitype/Dataset':
                mtype = 'dataset'
            hierarchy = etree.SubElement(node, util.nspath_eval('gmd:hierarchyLevel', self.namespaces))
            hierarchy.append(_write_codelist_element('gmd:MD_ScopeCode', mtype, self.namespaces))

        if esn in ['summary', 'full']:
            # contact
            contact = etree.SubElement(node, util.nspath_eval('gmd:contact', self.namespaces))
            if caps is not None:
                CI_resp = etree.SubElement(contact, util.nspath_eval('gmd:CI_ResponsibleParty', self.namespaces)) 
                if hasattr(caps.provider.contact, 'name'):
                    ind_name = etree.SubElement(CI_resp, util.nspath_eval('gmd:individualName', self.namespaces))
                    etree.SubElement(ind_name, util.nspath_eval('gco:CharacterString', self.namespaces)).text = caps.provider.contact.name
                if hasattr(caps.provider.contact, 'organization'):
                    if caps.provider.contact.organization is not None:
                        org_val = caps.provider.contact.organization
                    else:
                        org_val = caps.provider.name
                    org_name = etree.SubElement(CI_resp, util.nspath_eval('gmd:organisationName', self.namespaces))
                    etree.SubElement(org_name, util.nspath_eval('gco:CharacterString', self.namespaces)).text = org_val
                if hasattr(caps.provider.contact, 'position'):
                    pos_name = etree.SubElement(CI_resp, util.nspath_eval('gmd:positionName', self.namespaces))
                    etree.SubElement(pos_name, util.nspath_eval('gco:CharacterString', self.namespaces)).text = caps.provider.contact.position
                contact_info = etree.SubElement(CI_resp, util.nspath_eval('gmd:contactInfo', self.namespaces)) 
                ci_contact = etree.SubElement(contact_info, util.nspath_eval('gmd:CI_Contact', self.namespaces)) 
                if hasattr(caps.provider.contact, 'phone'):
                    phone = etree.SubElement(ci_contact, util.nspath_eval('gmd:phone', self.namespaces)) 
                    ci_phone = etree.SubElement(phone, util.nspath_eval('gmd:CI_Telephone', self.namespaces)) 
                    voice = etree.SubElement(ci_phone, util.nspath_eval('gmd:voice', self.namespaces)) 
                    etree.SubElement(voice, util.nspath_eval('gco:CharacterString', self.namespaces)).text = caps.provider.contact.phone
                    if hasattr(caps.provider.contact, 'fax'):
                        fax = etree.SubElement(ci_phone, util.nspath_eval('gmd:facsimile', self.namespaces)) 
                        etree.SubElement(fax, util.nspath_eval('gco:CharacterString', self.namespaces)).text = caps.provider.contact.fax
                address = etree.SubElement(ci_contact, util.nspath_eval('gmd:address', self.namespaces)) 
                ci_address = etree.SubElement(address, util.nspath_eval('gmd:CI_Address', self.namespaces)) 
                if hasattr(caps.provider.contact, 'address'):
                    delivery_point = etree.SubElement(ci_address, util.nspath_eval('gmd:deliveryPoint', self.namespaces)) 
                    etree.SubElement(delivery_point, util.nspath_eval('gco:CharacterString', self.namespaces)).text = caps.provider.contact.address
                if hasattr(caps.provider.contact, 'city'):
                    city = etree.SubElement(ci_address, util.nspath_eval('gmd:city', self.namespaces)) 
                    etree.SubElement(city, util.nspath_eval('gco:CharacterString', self.namespaces)).text = caps.provider.contact.city
                if hasattr(caps.provider.contact, 'region'):
                    admin_area = etree.SubElement(ci_address, util.nspath_eval('gmd:administrativeArea', self.namespaces)) 
                    etree.SubElement(admin_area, util.nspath_eval('gco:CharacterString', self.namespaces)).text = caps.provider.contact.region
                if hasattr(caps.provider.contact, 'postcode'):
                    postal_code = etree.SubElement(ci_address, util.nspath_eval('gmd:postalCode', self.namespaces)) 
                    etree.SubElement(postal_code, util.nspath_eval('gco:CharacterString', self.namespaces)).text = caps.provider.contact.postcode
                if hasattr(caps.provider.contact, 'country'):
                    country = etree.SubElement(ci_address, util.nspath_eval('gmd:country', self.namespaces)) 
                    etree.SubElement(country, util.nspath_eval('gco:CharacterString', self.namespaces)).text = caps.provider.contact.country
                if hasattr(caps.provider.contact, 'email'):
                    email = etree.SubElement(ci_address, util.nspath_eval('gmd:electronicMailAddress', self.namespaces)) 
                    etree.SubElement(email, util.nspath_eval('gco:CharacterString', self.namespaces)).text = caps.provider.contact.email

                contact_url = None
                if hasattr(caps.provider, 'url'):
                    contact_url = caps.provider.url
                if hasattr(caps.provider.contact, 'url') and caps.provider.contact.url is not None:
                    contact_url = caps.provider.contact.url

                if contact_url is not None:
                    online_resource = etree.SubElement(ci_contact, util.nspath_eval('gmd:onlineResource', self.namespaces)) 
                    gmd_linkage = etree.SubElement(online_resource, util.nspath_eval('gmd:linkage', self.namespaces)) 
                    etree.SubElement(gmd_linkage, util.nspath_eval('gmd:URL', self.namespaces)).text = contact_url

                if hasattr(caps.provider.contact, 'role'):
                    role = etree.SubElement(CI_resp, util.nspath_eval('gmd:role', self.namespaces)) 
                    role_val = caps.provider.contact.role
                    if role_val is None:
                        role_val = 'pointOfContact'
                    etree.SubElement(role, util.nspath_eval('gmd:CI_RoleCode', self.namespaces), codeListValue=role_val, codeList='%s#CI_RoleCode' % CODELIST).text = role_val
            else:
                val = util.getqattr(result, queryables['apiso:OrganisationName']['dbcol'])
                if val:
                    CI_resp = etree.SubElement(contact, util.nspath_eval('gmd:CI_ResponsibleParty', self.namespaces))
                    org_name = etree.SubElement(CI_resp, util.nspath_eval('gmd:organisationName', self.namespaces))
                    etree.SubElement(org_name, util.nspath_eval('gco:CharacterString', self.namespaces)).text = val

            # date
            val = util.getqattr(result, queryables['apiso:Modified']['dbcol'])
            date = etree.SubElement(node, util.nspath_eval('gmd:dateStamp', self.namespaces))
            if val and val.find('T') != -1:
                dateel = 'gco:DateTime'
            else:
                dateel = 'gco:Date'
            etree.SubElement(date, util.nspath_eval(dateel, self.namespaces)).text = val

            metadatastandardname = 'ISO19115'
            metadatastandardversion = '2003/Cor.1:2006'

            if mtype == 'service':
                metadatastandardname = 'ISO19119'
                metadatastandardversion = '2005/PDAM 1'

            # metadata standard name
            standard = etree.SubElement(node, util.nspath_eval('gmd:metadataStandardName', self.namespaces))
            etree.SubElement(standard, util.nspath_eval('gco:CharacterString', self.namespaces)).text = metadatastandardname

            # metadata standard version
            standardver = etree.SubElement(node, util.nspath_eval('gmd:metadataStandardVersion', self.namespaces))
            etree.SubElement(standardver, util.nspath_eval('gco:CharacterString', self.namespaces)).text = metadatastandardversion

        # title
        val = util.getqattr(result, queryables['apiso:Title']['dbcol']) or ''
        identification = etree.SubElement(node, util.nspath_eval('gmd:identificationInfo', self.namespaces))

        if mtype == 'service':
           restagname = 'srv:SV_ServiceIdentification'
        else:
           restagname = 'gmd:MD_DataIdentification'
          
        resident = etree.SubElement(identification, util.nspath_eval(restagname, self.namespaces), id=idval)
        tmp2 = etree.SubElement(resident, util.nspath_eval('gmd:citation', self.namespaces))
        tmp3 = etree.SubElement(tmp2, util.nspath_eval('gmd:CI_Citation', self.namespaces))
        tmp4 = etree.SubElement(tmp3, util.nspath_eval('gmd:title', self.namespaces))
        etree.SubElement(tmp4, util.nspath_eval('gco:CharacterString', self.namespaces)).text = val

        # creation date
        val = util.getqattr(result, queryables['apiso:CreationDate']['dbcol'])
        if val is not None:
            tmp3.append(_write_date(val, 'creation', self.namespaces))
        # publication date
        val = util.getqattr(result, queryables['apiso:PublicationDate']['dbcol'])
        if val is not None:
            tmp3.append(_write_date(val, 'publication', self.namespaces))
        # revision date
        val = util.getqattr(result, queryables['apiso:RevisionDate']['dbcol'])
        if val is not None:
            tmp3.append(_write_date(val, 'revision', self.namespaces))

        if esn in ['summary', 'full']:
            # abstract
            val = util.getqattr(result, queryables['apiso:Abstract']['dbcol']) or ''
            tmp = etree.SubElement(resident, util.nspath_eval('gmd:abstract', self.namespaces))
            etree.SubElement(tmp, util.nspath_eval('gco:CharacterString', self.namespaces)).text = val

            # keywords
            kw = util.getqattr(result, queryables['apiso:Subject']['dbcol'])
            if kw is not None:
                md_keywords = etree.SubElement(resident, util.nspath_eval('gmd:descriptiveKeywords', self.namespaces))
                md_keywords.append(write_keywords(kw, self.namespaces))

            # spatial resolution
            val = util.getqattr(result, queryables['apiso:Denominator']['dbcol'])
            if val:
                tmp = etree.SubElement(resident, util.nspath_eval('gmd:spatialResolution', self.namespaces))
                tmp2 = etree.SubElement(tmp, util.nspath_eval('gmd:MD_Resolution', self.namespaces))
                tmp3 = etree.SubElement(tmp2, util.nspath_eval('gmd:equivalentScale', self.namespaces))
                tmp4 = etree.SubElement(tmp3, util.nspath_eval('gmd:MD_RepresentativeFraction', self.namespaces))
                tmp5 = etree.SubElement(tmp4, util.nspath_eval('gmd:denominator', self.namespaces))
                etree.SubElement(tmp5, util.nspath_eval('gco:Integer', self.namespaces)).text = str(val)

            # resource language
            val = util.getqattr(result, queryables['apiso:ResourceLanguage']['dbcol'])
            tmp = etree.SubElement(resident, util.nspath_eval('gmd:language', self.namespaces))
            etree.SubElement(tmp, util.nspath_eval('gco:CharacterString', self.namespaces)).text = val

            # topic category
            val = util.getqattr(result, queryables['apiso:TopicCategory']['dbcol'])
            if val:
                for v in val.split(','):
                    tmp = etree.SubElement(resident, util.nspath_eval('gmd:topicCategory', self.namespaces))
                    etree.SubElement(tmp, util.nspath_eval('gmd:MD_TopicCategoryCode', self.namespaces)).text = val

        # bbox extent
        val = util.getqattr(result, queryables['apiso:BoundingBox']['dbcol'])
        bboxel = write_extent(val, self.namespaces)
        if bboxel is not None and mtype != 'service':
            resident.append(bboxel)

        # service identification

        if mtype == 'service':
            # service type
            # service type version
            val = util.getqattr(result, queryables['apiso:ServiceType']['dbcol'])
            val2 = util.getqattr(result, queryables['apiso:ServiceTypeVersion']['dbcol'])
            if val is not None:
                tmp = etree.SubElement(resident, util.nspath_eval('srv:serviceType', self.namespaces))
                etree.SubElement(tmp, util.nspath_eval('gco:LocalName', self.namespaces)).text = val
                tmp = etree.SubElement(resident, util.nspath_eval('srv:serviceTypeVersion', self.namespaces))
                etree.SubElement(tmp, util.nspath_eval('gco:CharacterString', self.namespaces)).text = val2

            kw = util.getqattr(result, queryables['apiso:Subject']['dbcol'])
            if kw is not None:
                srv_keywords = etree.SubElement(resident, util.nspath_eval('srv:keywords', self.namespaces))
                srv_keywords.append(write_keywords(kw, self.namespaces))
                 
            if bboxel is not None:
                bboxel.tag = util.nspath_eval('srv:extent', self.namespaces)
                resident.append(bboxel)

            val = util.getqattr(result, queryables['apiso:CouplingType']['dbcol'])
            if val is not None:
                couplingtype = etree.SubElement(resident, util.nspath_eval('srv:couplingType', self.namespaces))
                etree.SubElement(couplingtype, util.nspath_eval('srv:SV_CouplingType', self.namespaces), codeListValue=val, codeList='%s#SV_CouplingType' % CODELIST).text = val

            if esn in ['summary', 'full']:
                # all service resources as coupled resources
                coupledresources = util.getqattr(result, queryables['apiso:OperatesOn']['dbcol'])
                operations = util.getqattr(result, queryables['apiso:Operation']['dbcol'])

                if coupledresources:
                    for val2 in coupledresources.split(','):
                        coupledres = etree.SubElement(resident, util.nspath_eval('srv:coupledResource', self.namespaces))
                        svcoupledres = etree.SubElement(coupledres, util.nspath_eval('srv:SV_CoupledResource', self.namespaces))
                        opname = etree.SubElement(svcoupledres, util.nspath_eval('srv:operationName', self.namespaces))
                        etree.SubElement(opname, util.nspath_eval('gco:CharacterString', self.namespaces)).text = _get_resource_opname(operations)
                        sid = etree.SubElement(svcoupledres, util.nspath_eval('srv:identifier', self.namespaces))
                        etree.SubElement(sid, util.nspath_eval('gco:CharacterString', self.namespaces)).text = val2

                # service operations
                if operations:
                    for i in operations.split(','):
                        oper = etree.SubElement(resident, util.nspath_eval('srv:containsOperations', self.namespaces))
                        tmp = etree.SubElement(oper, util.nspath_eval('srv:SV_OperationMetadata', self.namespaces))

                        tmp2 = etree.SubElement(tmp, util.nspath_eval('srv:operationName', self.namespaces))
                        etree.SubElement(tmp2, util.nspath_eval('gco:CharacterString', self.namespaces)).text = i

                        tmp3 = etree.SubElement(tmp, util.nspath_eval('srv:DCP', self.namespaces))
                        etree.SubElement(tmp3, util.nspath_eval('srv:DCPList', self.namespaces), codeList='%s#DCPList' % CODELIST, codeListValue='HTTPGet').text = 'HTTPGet' 

                        tmp4 = etree.SubElement(tmp, util.nspath_eval('srv:DCP', self.namespaces))
                        etree.SubElement(tmp4, util.nspath_eval('srv:DCPList', self.namespaces), codeList='%s#DCPList' % CODELIST, codeListValue='HTTPPost').text = 'HTTPPost' 

                        connectpoint = etree.SubElement(tmp, util.nspath_eval('srv:connectPoint', self.namespaces))
                        onlineres = etree.SubElement(connectpoint, util.nspath_eval('gmd:CI_OnlineResource', self.namespaces))
                        linkage = etree.SubElement(onlineres, util.nspath_eval('gmd:linkage', self.namespaces))
                        etree.SubElement(linkage, util.nspath_eval('gmd:URL', self.namespaces)).text = util.getqattr(result, self.context.md_core_model['mappings']['pycsw:Source'])

                # operates on resource(s)
                if coupledresources:
                    for i in coupledresources.split(','):
                        operates_on = etree.SubElement(resident, util.nspath_eval('srv:operatesOn', self.namespaces), uuidref=i)
                        operates_on.attrib[util.nspath_eval('xlink:href', self.namespaces)] = '%sservice=CSW&version=2.0.2&request=GetRecordById&outputschema=http://www.isotc211.org/2005/gmd&id=%s-%s' % (util.bind_url(self.url), idval, i)

        rlinks = util.getqattr(result, self.context.md_core_model['mappings']['pycsw:Links'])

        if rlinks:
            distinfo = etree.SubElement(node, util.nspath_eval('gmd:distributionInfo', self.namespaces))
            distinfo2 = etree.SubElement(distinfo, util.nspath_eval('gmd:MD_Distribution', self.namespaces))
            transopts = etree.SubElement(distinfo2, util.nspath_eval('gmd:transferOptions', self.namespaces))
            dtransopts = etree.SubElement(transopts, util.nspath_eval('gmd:MD_DigitalTransferOptions', self.namespaces))

            for link in rlinks.split('^'):
                linkset = link.split(',')
                online = etree.SubElement(dtransopts, util.nspath_eval('gmd:onLine', self.namespaces))
                online2 = etree.SubElement(online, util.nspath_eval('gmd:CI_OnlineResource', self.namespaces))

                linkage = etree.SubElement(online2, util.nspath_eval('gmd:linkage', self.namespaces))
                etree.SubElement(linkage, util.nspath_eval('gmd:URL', self.namespaces)).text = linkset[-1]

                protocol = etree.SubElement(online2, util.nspath_eval('gmd:protocol', self.namespaces))
                etree.SubElement(protocol, util.nspath_eval('gco:CharacterString', self.namespaces)).text = linkset[2]

                name = etree.SubElement(online2, util.nspath_eval('gmd:name', self.namespaces))
                etree.SubElement(name, util.nspath_eval('gco:CharacterString', self.namespaces)).text = linkset[0]

                desc = etree.SubElement(online2, util.nspath_eval('gmd:description', self.namespaces))
                etree.SubElement(desc, util.nspath_eval('gco:CharacterString', self.namespaces)).text = linkset[1]

        return node