Project

General

Profile

« Previous | Next » 

Revision 25

In data2xml, added shortcut for lookahead assertion using ! symbol

View differences:

scripts/data2xml/NYBG-VegBank-VegX_mapping.csv
4 4
"InstitutionCode","/taxonInterpretation/museum_ID->/party/OrganizationName/_name/firstName","/*s/taxonNameUsageConcept/partyWithRole/partyID->/parties/party/organizationName/_name/firstName"
5 5
"CollectionCode","/taxonInterpretation/museum_ID->/party/OrganizationName/_name/lastName","/*s/taxonNameUsageConcept/partyWithRole/partyID->/parties/party/organizationName/_name/lastName"
6 6
"CatalogNumber","/taxonInterpretation/museumAccessionNumber","/*s/taxonNameUsageConcept/voucher"
7
"ScientificName","/plantName/plantName","/*s/taxonNameUsageConcept->/*s/taxonDetermination[taxonNameUsageConceptID]/*s/taxonRelationshipAssertion/assertion/taxonNameID->/*s/taxonName/Simple"
7
"ScientificName","/plantName/plantName","/*s/taxonNameUsageConcept->/*s/taxonDetermination[taxonNameUsageConceptID]/*s/taxonRelationshipAssertion!/assertion/taxonNameID->/*s/taxonName/Simple"
8 8
"BasisOfRecord",,
9
"Kingdom","/plantName[plantStatus/plantLevel=Kingdom]/plantName","/*s/taxonConcept[Rank/@code=reg]/Name"
10
"Phylum","/plantName[plantStatus/plantLevel=Subkingdom]/plantName","/*s/taxonConcept[Rank/@code=phyl_div]/Name"
11
"Class","/plantName[plantStatus/plantLevel=Class]/plantName","/*s/taxonConcept[Rank/@code=cl]/Name"
12
"Order","/plantName[plantStatus/plantLevel=Order]/plantName","/*s/taxonConcept[Rank/@code=ord]/Name"
13
"Family","/plantName[plantStatus/plantLevel=Family]/plantName","/*s/taxonConcept[Rank/@code=fam]/Name"
14
"Genus","/plantName[plantStatus/plantLevel=Genus]/plantName","/*s/taxonConcept[Rank/@code=gen]/Name"
15
"Species","/plantName[plantStatus/plantLevel=Species]/plantName","/*s/taxonConcept[Rank/@code=sp]/Name"
16
"Subspecies","/plantName[plantStatus/plantLevel=Subspecies]/plantName","/*s/taxonConcept[Rank/@code=ssp]/Name"
17
"ScientificNameAuthor","/plantConcept/reference_ID->/referenceParty/{givenName,surname}","/*s/taxonConcept/AccordingTo/Simple"
9
"Kingdom","/plantName[plantStatus/plantLevel=Kingdom]/plantName","/*s/taxonNameUsageConcept->/*s/taxonDetermination[taxonNameUsageConceptID]/*s/taxonRelationshipAssertion!/assertion/taxonConceptID->/*s/taxonConcept[Rank/@code=reg]/Name"
10
"Phylum","/plantName[plantStatus/plantLevel=Subkingdom]/plantName","/*s/taxonNameUsageConcept->/*s/taxonDetermination[taxonNameUsageConceptID]/*s/taxonRelationshipAssertion!/assertion/taxonConceptID->/*s/taxonConcept[Rank/@code=phyl_div]/Name"
11
"Class","/plantName[plantStatus/plantLevel=Class]/plantName","/*s/taxonNameUsageConcept->/*s/taxonDetermination[taxonNameUsageConceptID]/*s/taxonRelationshipAssertion!/assertion/taxonConceptID->/*s/taxonConcept[Rank/@code=cl]/Name"
12
"Order","/plantName[plantStatus/plantLevel=Order]/plantName","/*s/taxonNameUsageConcept->/*s/taxonDetermination[taxonNameUsageConceptID]/*s/taxonRelationshipAssertion!/assertion/taxonConceptID->/*s/taxonConcept[Rank/@code=ord]/Name"
13
"Family","/plantName[plantStatus/plantLevel=Family]/plantName","/*s/taxonNameUsageConcept->/*s/taxonDetermination[taxonNameUsageConceptID]/*s/taxonRelationshipAssertion!/assertion/taxonConceptID->/*s/taxonConcept[Rank/@code=fam]/Name"
14
"Genus","/plantName[plantStatus/plantLevel=Genus]/plantName","/*s/taxonNameUsageConcept->/*s/taxonDetermination[taxonNameUsageConceptID]/*s/taxonRelationshipAssertion!/assertion/taxonConceptID->/*s/taxonConcept[Rank/@code=gen]/Name"
15
"Species","/plantName[plantStatus/plantLevel=Species]/plantName","/*s/taxonNameUsageConcept->/*s/taxonDetermination[taxonNameUsageConceptID]/*s/taxonRelationshipAssertion!/assertion/taxonConceptID->/*s/taxonConcept[Rank/@code=sp]/Name"
16
"Subspecies","/plantName[plantStatus/plantLevel=Subspecies]/plantName","/*s/taxonNameUsageConcept->/*s/taxonDetermination[taxonNameUsageConceptID]/*s/taxonRelationshipAssertion!/assertion/taxonConceptID->/*s/taxonConcept[Rank/@code=ssp]/Name"
17
"ScientificNameAuthor","/plantConcept/reference_ID->/referenceParty/{givenName,surname}","/*s/taxonNameUsageConcept->/*s/taxonDetermination[taxonNameUsageConceptID]/*s/taxonRelationshipAssertion!/assertion/taxonConceptID->/*s/taxonConcept/AccordingTo/Simple"
18 18
"IdentifiedBy","/taxonInterpretation/PARTY_ID->/party/{givenName,middleName,surName}","/*s/taxonNameUsageConcept->/*s/taxonDetermination[taxonNameUsageConceptID]/partyWithRole[role=identifier]/partyID->/parties/party/individualName/{givenName,surName}"
19 19
"YearIdentified","/taxonInterpretation/interpretationDate/_date/year","/*s/taxonNameUsageConcept->/*s/taxonDetermination[taxonNameUsageConceptID]/date/_date/year"
20 20
"MonthIdentified","/taxonInterpretation/interpretationDate/_date/month","/*s/taxonNameUsageConcept->/*s/taxonDetermination[taxonNameUsageConceptID]/date/_date/month"
......
41 41
"MaximumElevation","/plot/elevation/max,plot/elevationRange/to","/*s/plot/geospatial/maximumElevationInMeters"
42 42
"MinimumDepth","/observation/waterDepth/min","/*s/plot/geospatial/minimumDepthInMeters"
43 43
"MaximumDepth","/observation/waterDepth/max","/*s/plot/geospatial/maximumDepthInMeters"
44
"Sex","/userDefined[tableName=taxonInterpretation,userDefinedName=<name>]/definedValue ","/*s/individualOrganismObservation/simpleUserdefined[name=sex]/value"
44
"Sex","/userDefined[tableName=taxonInterpretation,userDefinedName=sex]/definedValue ","/*s/individualOrganismObservation/simpleUserdefined[name=sex]/value"
45 45
"PreparationType",,
46 46
"IndividualCount",,
47 47
"PreviousCatalogNumber",,
48 48
"RelationshipType",,
49 49
"RelatedCatalogItem",,
50 50
"Notes","/taxonInterpretation/notes","/*s/taxonNameUsageConcept/note/text"
51
"Habitat","/userDefined[tableName=stemLocation,userDefinedName=<name>]/definedValue ","/*s/individualOrganismObservation/simpleUserdefined[name=habitat]/value"
52
"PlantFungusDescription","/userDefined[tableName=stemLocation,userDefinedName=<name>]/definedValue ","/*s/individualOrganismObservation/simpleUserdefined[name=plantFungusDescription]/value"
53
"Substrate","/userDefined[tableName=stemLocation,userDefinedName=<name>]/definedValue ","/*s/individualOrganismObservation/simpleUserdefined[name=substrate]/value"
54
"Vegetation","/userDefined[tableName=stemLocation,userDefinedName=<name>]/definedValue ","/*s/individualOrganismObservation/simpleUserdefined[name=vegetation]/value"
51
"Habitat","/userDefined[tableName=stemLocation,userDefinedName=habitat]/definedValue ","/*s/individualOrganismObservation/simpleUserdefined[name=habitat]/value"
52
"PlantFungusDescription","/userDefined[tableName=stemLocation,userDefinedName=plantFungusDescription]/definedValue ","/*s/individualOrganismObservation/simpleUserdefined[name=plantFungusDescription]/value"
53
"Substrate","/userDefined[tableName=stemLocation,userDefinedName=substrate]/definedValue ","/*s/individualOrganismObservation/simpleUserdefined[name=substrate]/value"
54
"Vegetation","/userDefined[tableName=stemLocation,userDefinedName=vegetation]/definedValue ","/*s/individualOrganismObservation/simpleUserdefined[name=vegetation]/value"
55 55
"UniqueNYInternalRecordNumber",,
scripts/data2xml/xpath.py
19 19
    def __repr__(self):
20 20
        str_ = ''
21 21
        if self.is_attr: str_ += '@'
22
        str_ += self.name+repr(self.attrs)+'='+repr(self.value)
22
        str_ += self.name
23
        if self.attrs != []: str_ += repr(self.attrs)
24
        if self.value != None: str_ += '='+repr(self.value)
23 25
        if self.is_ptr: str_ += '->'
24 26
        return str_
25 27
    
......
36 38
    
37 39
    def _path(self):
38 40
        tree = []
41
        fork_idx = None
42
        elem_idx = 0
39 43
        while True:
40 44
            elem = XpathElem(is_attr=self._match_str('@'), name=self._fields())
41 45
            if self._match_str('['):
42 46
                elem.attrs = self._attrs()
43 47
                self._match_str(']', required=True)
44 48
            elem.is_ptr = self._match_str('->')
49
            if not elem.is_ptr and self._match_str('!'): fork_idx = elem_idx
45 50
            tree.append(elem)
46 51
            if not self._match_str('/'): break
52
            elem_idx += 1
53
        # Add lookahead assertion for rest of path
54
        if fork_idx != None: tree[fork_idx].attrs.append(tree[fork_idx+1:])
47 55
        return tree
48 56
    
49 57
    def _fields(self):
......
116 124
        
117 125
        # Follow pointer
118 126
        if elem.is_ptr:
119
            target = deepcopy(path[elem_idx+1:]) # rest of path
120
            attrs = target[types_id_level].attrs
127
            path = deepcopy(path[elem_idx+1:]) # rest of path
128
            attrs = path[types_id_level].attrs
121 129
            if len(attrs) >= 1 and value(attrs[0]) == None:
122 130
                # backward (child-to-parent) pointer with target ID attr
123 131
                set_value(attrs[0], xml_util.get_id(node))
124 132
            else: # forward (parent-to-child) pointer
125 133
                id_ = xml_util.value(node)
126
                if id_ == None:
134
                obj_path = path[:types_id_level+1] # target object
135
                if id_ == None or get(doc, obj_path, False, True) == None:
136
                    # no target or target attrs don't match
127 137
                    if not create: return None
138
                    
128 139
                    # Use last target object's ID + 1
129
                    obj = get(doc, target[:types_id_level+1], False, True)
130
                    if obj != None: id_ = str(int(xml_util.get_id(obj)) + 1)
140
                    last_path = deepcopy(obj_path)
141
                    last_path[-1].attrs = [] # just get by tag name
142
                    last = get(doc, last_path, False, True)
143
                    if last != None: id_ = str(int(xml_util.get_id(last)) + 1)
131 144
                    else: id_ = '0'
145
                    
146
                    # Will append if target attrs didn't match. Place ! in XPath
147
                    # after element to fork at to avoid this.
132 148
                    xml_util.set_value(doc, node, id_)
133 149
                else: last_only = False
134
                set_id(target, id_)
135
            return get(doc, target, create, last_only)
150
                set_id(path, id_)
151
            return get(doc, path, create, last_only)
136 152
        
137 153
        parent = node
138 154
        elem_idx += 1

Also available in: Unified diff