Skip to content

Commit 1ea2d42

Browse files
feat: new hash removal techniques with translate() + sample output
After removing the remote hashing call, it was time to replace the URL-encoding. However, applying a consistent and unified technique to both `rr:template` and `rml:reference` proved to be challenging, in order to realize the following substitution requirements: - `Q\{[^}]+\}` with nothing - `\[(\d+)\]` with `_\1` - `/` with `.` - `encode-for-uri()` function with `replace()` - adding periods (`.`) in the concat functions (revisiting the need for it, first) - checking any double-encoding problems (`rr:template` already does URI-encoding) String substitution techniques like these rely on "regular expressions", aka regex. In regex, certain characters have special meaning, so "escaping" them (typically with a backslash `\`) is necessary to force literal interpretation by the regex engine. This is made more complicated when multiple processing subsystems are involved -- in this case the RML engine (RMLMapper), the RML specifications it follows, Saxon the XPath processor, and Turtle the RDF syntax used to write the RML rules. Unfortunately, it did not seem possible to use escape characters or the necessary characters in `rr:template` without escaping, such as curly braces `{}` and square braces `[]`. Fortunately, after several rounds of failed experiments, a trick with a pair of unassuming XPath functions was discovered. With `translate()` and `codepoints-to-string()`, one is able to replace certain characters with alternatives, where the latter transforms a given code to an ASCII character, and the former replaces a given sequence of those with another. With this we could finally replace the stubborn `Q{}` namespace qualifier in the XPath returned by `path()`, when in an `rr:template`. We develop here two separate implementations of URI rewrites: (i) a standard regex substitution (with three levels of replacements) for `rml:reference`, and (ii) a clever one with the aforementioned technique for `rr:template` (that has the `{}` characters reserved for itself and cannot interpret backslash escapes). P.S: This technique will NOT work if in the source there is more than one XML element with the same name but different prefix. Co-authored-by: csnyulas <csongor.nyulas@gmail.com>
1 parent 1232429 commit 1ea2d42

62 files changed

Lines changed: 337 additions & 337 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

src/mappings-can/Business-can.rml.ttl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ tedm:MG-Identifier-identifier-Person_ND-UBO a rr:TriplesMap ;
113113
rr:subjectMap
114114
[
115115
rdfs:label "ND-UBO" ;
116-
rr:template "http://data.europa.eu/a4g/resource/id_{replace(replace(/*/cbc:ID[@schemeName='notice-id'], ' ', '-' ), '/' , '-')}_BeneficialOwnerTechnicalIdentifier_{encode-for-uri(path())}" ;
116+
rr:template "http://data.europa.eu/a4g/resource/id_{replace(replace(/*/cbc:ID[@schemeName='notice-id'], ' ', '-' ), '/' , '-')}_BeneficialOwnerTechnicalIdentifier_{replace(translate(path(), concat(codepoints-to-string(123), codepoints-to-string(125), '/[]'), ' _'), 'Q .*? ', '')}" ;
117117
rr:class adms:Identifier
118118
] ;
119119
rr:predicateObjectMap
@@ -213,7 +213,7 @@ tedm:MG-Address-registeredAddress-Person_ND-UBOAddress a rr:TriplesMap ;
213213
rr:subjectMap
214214
[
215215
rdfs:label "ND-UBOAddress" ;
216-
rr:template "http://data.europa.eu/a4g/resource/id_{replace(replace(/*/cbc:ID[@schemeName='notice-id'], ' ', '-' ), '/' , '-')}_UBOAddress_{encode-for-uri(path())}" ;
216+
rr:template "http://data.europa.eu/a4g/resource/id_{replace(replace(/*/cbc:ID[@schemeName='notice-id'], ' ', '-' ), '/' , '-')}_UBOAddress_{replace(translate(path(), concat(codepoints-to-string(123), codepoints-to-string(125), '/[]'), ' _'), 'Q .*? ', '')}" ;
217217
rr:class locn:Address
218218
] ;
219219
rr:predicateObjectMap

src/mappings-can/Contract-can.rml.ttl

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ tedm:MG-Identifier-identifier-Contract_ND-SettledContract a rr:TriplesMap ;
3535
rr:subjectMap
3636
[
3737
rdfs:label "ND-SettledContract" ;
38-
rml:reference "if (exists(efac:ContractReference/cbc:ID)) then 'http://data.europa.eu/a4g/resource/id_' || replace(replace(/*/cbc:ID[@schemeName='notice-id'], ' ', '-' ), '/' , '-') || '_SettledContractIdentifier_' || encode-for-uri(path(.)) else null" ;
38+
rml:reference "if (exists(efac:ContractReference/cbc:ID)) then 'http://data.europa.eu/a4g/resource/id_' || replace(replace(/*/cbc:ID[@schemeName='notice-id'], ' ', '-' ), '/' , '-') || '_SettledContractIdentifier_' || replace(replace(replace(path(.), 'Q\\{[^}]+\\}', ''), '\\[([0-9]+)\\]', '$1'), '/', '_') else null" ;
3939
rr:class adms:Identifier
4040
] ;
4141
rr:predicateObjectMap
@@ -217,7 +217,7 @@ tedm:MG-Fund_ND-SettledContract a rr:TriplesMap ;
217217
rr:subjectMap
218218
[
219219
rdfs:label "ND-SettledContract" ;
220-
rml:reference "if (exists(efac:Funding)) then 'http://data.europa.eu/a4g/resource/id_' || replace(replace(/*/cbc:ID[@schemeName='notice-id'], ' ', '-' ), '/' , '-') || '_ContractFund_' || encode-for-uri(path(.)) else null" ;
220+
rml:reference "if (exists(efac:Funding)) then 'http://data.europa.eu/a4g/resource/id_' || replace(replace(/*/cbc:ID[@schemeName='notice-id'], ' ', '-' ), '/' , '-') || '_ContractFund_' || replace(replace(replace(path(.), 'Q\\{[^}]+\\}', ''), '\\[([0-9]+)\\]', '$1'), '/', '_') else null" ;
221221
rr:class epo:Fund
222222
] ;
223223
.
@@ -232,7 +232,7 @@ tedm:MG-Fund-isFundedBy-Contract_ND-SettledContract a rr:TriplesMap ;
232232
rr:subjectMap
233233
[
234234
rdfs:label "ND-SettledContract" ;
235-
rml:reference "if (exists(efac:Funding)) then 'http://data.europa.eu/a4g/resource/id_' || replace(replace(/*/cbc:ID[@schemeName='notice-id'], ' ', '-' ), '/' , '-') || '_ContractFund_' || encode-for-uri(path(.)) else null" ;
235+
rml:reference "if (exists(efac:Funding)) then 'http://data.europa.eu/a4g/resource/id_' || replace(replace(/*/cbc:ID[@schemeName='notice-id'], ' ', '-' ), '/' , '-') || '_ContractFund_' || replace(replace(replace(path(.), 'Q\\{[^}]+\\}', ''), '\\[([0-9]+)\\]', '$1'), '/', '_') else null" ;
236236
rr:class epo:Fund
237237
] ;
238238
rr:predicateObjectMap
@@ -263,7 +263,7 @@ tedm:MG-Identifier-identifier-Fund-isFundedBy-Contract_ND-ContractEUFunds a rr:T
263263
rr:subjectMap
264264
[
265265
rdfs:label "ND-ContractEUFunds" ;
266-
rml:reference "if (exists(efbc:FinancingIdentifier)) then 'http://data.europa.eu/a4g/resource/id_' || replace(replace(/*/cbc:ID[@schemeName='notice-id'], ' ', '-' ), '/' , '-') || '_ContractFundIdentifier_' || encode-for-uri(path(..)) else null" ;
266+
rml:reference "if (exists(efbc:FinancingIdentifier)) then 'http://data.europa.eu/a4g/resource/id_' || replace(replace(/*/cbc:ID[@schemeName='notice-id'], ' ', '-' ), '/' , '-') || '_ContractFundIdentifier_' || replace(replace(replace(path(..), 'Q\\{[^}]+\\}', ''), '\\[([0-9]+)\\]', '$1'), '/', '_') else null" ;
267267
rr:class adms:Identifier
268268
] ;
269269
rr:predicateObjectMap
@@ -298,7 +298,7 @@ tedm:MG-Fund-isFundedBy-Contract_ND-ContractEUFunds a rr:TriplesMap ;
298298
rr:subjectMap
299299
[
300300
rdfs:label "ND-ContractEUFunds" ;
301-
rml:reference "if((exists(cbc:FundingProgramCode)) or (exists(cbc:Description))) then 'http://data.europa.eu/a4g/resource/id_' || replace(replace(/*/cbc:ID[@schemeName='notice-id'], ' ', '-' ), '/' , '-') || '_ContractFund_' || encode-for-uri(path(..)) else null" ;
301+
rml:reference "if((exists(cbc:FundingProgramCode)) or (exists(cbc:Description))) then 'http://data.europa.eu/a4g/resource/id_' || replace(replace(/*/cbc:ID[@schemeName='notice-id'], ' ', '-' ), '/' , '-') || '_ContractFund_' || replace(replace(replace(path(..), 'Q\\{[^}]+\\}', ''), '\\[([0-9]+)\\]', '$1'), '/', '_') else null" ;
302302
rr:class epo:Fund
303303
] ;
304304

@@ -609,7 +609,7 @@ tedm:MG-langString-description-Fund-isFundedBy-Contract_ND-ContractEUFunds a rr:
609609
rr:subjectMap [
610610
rr:class epo-not:Fund ;
611611
rdfs:label "ND-ContractEUFunds" ;
612-
rml:reference "'http://data.europa.eu/a4g/resource/id_' || replace(replace(/*/cbc:ID[@schemeName='notice-id'], ' ', '-' ), '/' , '-') || '_ContractFund_' || encode-for-uri(path(../..))" ;
612+
rml:reference "'http://data.europa.eu/a4g/resource/id_' || replace(replace(/*/cbc:ID[@schemeName='notice-id'], ' ', '-' ), '/' , '-') || '_ContractFund_' || replace(replace(replace(path(../..), 'Q\\{[^}]+\\}', ''), '\\[([0-9]+)\\]', '$1'), '/', '_')" ;
613613
] ;
614614
rr:predicateObjectMap [
615615
tedm:minSDKVersion "1.9.1" ;

src/mappings-can/ContractModificationInformation.rml.ttl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ tedm:MG-ContractModificationInformation_ND-ModificationReason a rr:TriplesMap ;
3636
rr:subjectMap
3737
[
3838
rdfs:label "ND-ModificationReason" ;
39-
rml:reference "if (exists(cbc:ReasonCode) or exists(efbc:ReasonDescription)) then 'http://data.europa.eu/a4g/resource/id_' || replace(replace(/*/cbc:ID[@schemeName='notice-id'], ' ', '-' ), '/' , '-') || '_ContractModificationInformation_' || encode-for-uri(path(..)) else null" ;
39+
rml:reference "if (exists(cbc:ReasonCode) or exists(efbc:ReasonDescription)) then 'http://data.europa.eu/a4g/resource/id_' || replace(replace(/*/cbc:ID[@schemeName='notice-id'], ' ', '-' ), '/' , '-') || '_ContractModificationInformation_' || replace(replace(replace(path(..), 'Q\\{[^}]+\\}', ''), '\\[([0-9]+)\\]', '$1'), '/', '_') else null" ;
4040
rr:class epo-con:ContractModificationInformation
4141
] ;
4242
rr:predicateObjectMap
@@ -81,7 +81,7 @@ tedm:MG-ContractAmendment-concernsContractAmendment-ContractModificationInformat
8181
rr:subjectMap
8282
[
8383
rdfs:label "ND-ModificationReason" ;
84-
rr:template "http://data.europa.eu/a4g/resource/id_{replace(replace(/*/cbc:ID[@schemeName='notice-id'], ' ', '-' ), '/' , '-')}_ContractAmendment_{encode-for-uri(path(..))}" ;
84+
rr:template "http://data.europa.eu/a4g/resource/id_{replace(replace(/*/cbc:ID[@schemeName='notice-id'], ' ', '-' ), '/' , '-')}_ContractAmendment_{replace(translate(path(..), concat(codepoints-to-string(123), codepoints-to-string(125), '/[]'), ' _'), 'Q .*? ', '')}" ;
8585
rr:class epo-con:ContractAmendment
8686
] ;
8787
.
@@ -96,7 +96,7 @@ tedm:MG-langString-hasModificationReasonDescription-ContractModificationInformat
9696
rr:subjectMap [
9797
rr:class epo-con:ContractModificationInformation ;
9898
rdfs:label "ND-ModificationReason" ;
99-
rr:template "http://data.europa.eu/a4g/resource/id_{replace(replace(/*/cbc:ID[@schemeName='notice-id'], ' ', '-' ), '/' , '-')}_ContractModificationInformation_{encode-for-uri(path(../..))}" ;
99+
rr:template "http://data.europa.eu/a4g/resource/id_{replace(replace(/*/cbc:ID[@schemeName='notice-id'], ' ', '-' ), '/' , '-')}_ContractModificationInformation_{replace(translate(path(../..), concat(codepoints-to-string(123), codepoints-to-string(125), '/[]'), ' _'), 'Q .*? ', '')}" ;
100100
] ;
101101
rr:predicateObjectMap [
102102
rr:predicate epo:hasModificationReasonDescription ;
@@ -134,7 +134,7 @@ tedm:MG-langString-hasModificationReasonDescription-ContractModificationInformat
134134
rr:subjectMap [
135135
rr:class epo-con:ContractModificationInformation ;
136136
rdfs:label "ND-ModificationReason" ;
137-
rr:template "http://data.europa.eu/a4g/resource/id_{replace(replace(/*/cbc:ID[@schemeName='notice-id'], ' ', '-' ), '/' , '-')}_ContractModificationInformation_{encode-for-uri(path(../..))}" ;
137+
rr:template "http://data.europa.eu/a4g/resource/id_{replace(replace(/*/cbc:ID[@schemeName='notice-id'], ' ', '-' ), '/' , '-')}_ContractModificationInformation_{replace(translate(path(../..), concat(codepoints-to-string(123), codepoints-to-string(125), '/[]'), ' _'), 'Q .*? ', '')}" ;
138138
] ;
139139
rr:predicateObjectMap [
140140
rr:predicate epo:hasModificationDescription ;

src/mappings-can/GreenProcurement-can.rml.ttl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ tedm:MG-GreenProcurement-concernsGreenProcurement-VehicleInformation_ND-Strategi
3535
rr:subjectMap
3636
[
3737
rdfs:label "ND-StrategicProcurementInformationLotResult" ;
38-
rr:template "http://data.europa.eu/a4g/resource/id_{replace(replace(/*/cbc:ID[@schemeName='notice-id'], ' ', '-' ), '/' , '-')}_GreenProcurement_{encode-for-uri(path())}" ;
38+
rr:template "http://data.europa.eu/a4g/resource/id_{replace(replace(/*/cbc:ID[@schemeName='notice-id'], ' ', '-' ), '/' , '-')}_GreenProcurement_{replace(translate(path(), concat(codepoints-to-string(123), codepoints-to-string(125), '/[]'), ' _'), 'Q .*? ', '')}" ;
3939
rr:class epo:GreenProcurement
4040
] ;
4141
.

src/mappings-can/Lot-compl.rml.ttl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ tedm:MG-ContractTerm-foreseesContractSpecificTerm-Lot_ND-LotDuration a rr:Triple
3535
rr:subjectMap
3636
[
3737
rdfs:label "ND-LotDuration";
38-
rml:reference "if (exists(cbc:Description)) then 'http://data.europa.eu/a4g/resource/id_' || replace(replace(/*/cbc:ID[@schemeName='notice-id'], ' ', '-' ), '/' , '-') || '_ContractTerm_' || encode-for-uri(path()) else null" ;
38+
rml:reference "if (exists(cbc:Description)) then 'http://data.europa.eu/a4g/resource/id_' || replace(replace(/*/cbc:ID[@schemeName='notice-id'], ' ', '-' ), '/' , '-') || '_ContractTerm_' || replace(replace(replace(path(), 'Q\\{[^}]+\\}', ''), '\\[([0-9]+)\\]', '$1'), '/', '_') else null" ;
3939
rr:class epo:ContractTerm
4040
] ;
4141
.
@@ -81,7 +81,7 @@ tedm:MG-langString-hasExceedingDurationJustification-ContractTerm_ND-LotDuration
8181
rr:subjectMap [
8282
rr:class epo:ContractTerm ;
8383
rdfs:label "ND-LotDuration" ;
84-
rr:template "http://data.europa.eu/a4g/resource/id_{replace(replace(/*/cbc:ID[@schemeName='notice-id'], ' ', '-' ), '/' , '-')}_ContractTerm_{encode-for-uri(path(..))}" ;
84+
rr:template "http://data.europa.eu/a4g/resource/id_{replace(replace(/*/cbc:ID[@schemeName='notice-id'], ' ', '-' ), '/' , '-')}_ContractTerm_{replace(translate(path(..), concat(codepoints-to-string(123), codepoints-to-string(125), '/[]'), ' _'), 'Q .*? ', '')}" ;
8585
] ;
8686
rr:predicateObjectMap [
8787
rr:predicate epo:hasExceedingDurationJustification ;

src/mappings-can/LotAwardOutcome-can.rml.ttl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ tedm:MG-MonetaryValue-hasApproximateFrameworkAgreementValue-LotAwardOutcome_ND-L
123123
rr:subjectMap
124124
[
125125
rdfs:label "ND-LotResultFAValues";
126-
rml:reference "if (exists(efbc:ReestimatedValueAmount)) then 'http://data.europa.eu/a4g/resource/id_' || replace(replace(/*/cbc:ID[@schemeName='notice-id'], ' ', '-' ), '/' , '-') || '_MonetaryValue_' || encode-for-uri(path(.)) else null" ;
126+
rml:reference "if (exists(efbc:ReestimatedValueAmount)) then 'http://data.europa.eu/a4g/resource/id_' || replace(replace(/*/cbc:ID[@schemeName='notice-id'], ' ', '-' ), '/' , '-') || '_MonetaryValue_' || replace(replace(replace(path(.), 'Q\\{[^}]+\\}', ''), '\\[([0-9]+)\\]', '$1'), '/', '_') else null" ;
127127
rr:class epo:MonetaryValue
128128
] ;
129129
rr:predicateObjectMap
@@ -168,7 +168,7 @@ tedm:MG-MonetaryValue-hasFrameworkAgreementMaximumValue-LotAwardOutcome_ND-LotRe
168168
rr:subjectMap
169169
[
170170
rdfs:label "ND-LotResultFAValues";
171-
rml:reference "if (exists(cbc:MaximumValueAmount)) then 'http://data.europa.eu/a4g/resource/id_' || replace(replace(/*/cbc:ID[@schemeName='notice-id'], ' ', '-' ), '/' , '-') || '_FrameworkAgreementMaximumMonetaryValue_' || encode-for-uri(path(.)) else null" ;
171+
rml:reference "if (exists(cbc:MaximumValueAmount)) then 'http://data.europa.eu/a4g/resource/id_' || replace(replace(/*/cbc:ID[@schemeName='notice-id'], ' ', '-' ), '/' , '-') || '_FrameworkAgreementMaximumMonetaryValue_' || replace(replace(replace(path(.), 'Q\\{[^}]+\\}', ''), '\\[([0-9]+)\\]', '$1'), '/', '_') else null" ;
172172
rr:class epo:MonetaryValue
173173
] ;
174174
rr:predicateObjectMap

src/mappings-can/LotGroup-can.rml.ttl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ tedm:MG-LotGroup_ND-NoticeResultGroupFA a rr:TriplesMap ;
173173
# rr:subjectMap
174174
# [
175175
# rdfs:label "ND-NoticeResultGroupFA";
176-
# rml:reference "if (exists(efbc:GroupFrameworkReestimatedValueAmount)) then 'http://data.europa.eu/a4g/resource/id_' || replace(replace(/*/cbc:ID[@schemeName='notice-id'], ' ', '-' ), '/' , '-') || '_MonetaryValue_' || encode-for-uri(path()) else null" ;
176+
# rml:reference "if (exists(efbc:GroupFrameworkReestimatedValueAmount)) then 'http://data.europa.eu/a4g/resource/id_' || replace(replace(/*/cbc:ID[@schemeName='notice-id'], ' ', '-' ), '/' , '-') || '_MonetaryValue_' || replace(replace(replace(path(), 'Q\\{[^}]+\\}', ''), '\\[([0-9]+)\\]', '$1'), '/', '_') else null" ;
177177
# rr:class epo:MonetaryValue
178178
# ] ;
179179
# rr:predicateObjectMap

src/mappings-can/LotGroupAwardInformation-can.rml.ttl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ tedm:MG-MonetaryValue-hasGroupFrameworkAgreementMaximumValue-LotGroupAwardInform
3535
rr:subjectMap
3636
[
3737
rdfs:label "ND-NoticeResultGroupFA";
38-
rml:reference "if (exists(efbc:GroupFrameworkMaximumValueAmount)) then 'http://data.europa.eu/a4g/resource/id_' || replace(replace(/*/cbc:ID[@schemeName='notice-id'], ' ', '-' ), '/' , '-') || '_MonetaryValue_' || encode-for-uri(path(.)) else null" ;
38+
rml:reference "if (exists(efbc:GroupFrameworkMaximumValueAmount)) then 'http://data.europa.eu/a4g/resource/id_' || replace(replace(/*/cbc:ID[@schemeName='notice-id'], ' ', '-' ), '/' , '-') || '_MonetaryValue_' || replace(replace(replace(path(.), 'Q\\{[^}]+\\}', ''), '\\[([0-9]+)\\]', '$1'), '/', '_') else null" ;
3939
rr:class epo:MonetaryValue
4040
] ;
4141
rr:predicateObjectMap
@@ -77,7 +77,7 @@ tedm:MG-LotGroupAwardInformation_ND-NoticeResultGroupFA a rr:TriplesMap ;
7777
rr:subjectMap
7878
[
7979
rdfs:label "ND-LotsGroupFA";
80-
rml:reference "if (exists(efbc:GroupFrameworkMaximumValueAmount)) then 'http://data.europa.eu/a4g/resource/id_' || replace(replace(/*/cbc:ID[@schemeName='notice-id'], ' ', '-' ), '/' , '-') || '_LotGroupAwardInformation_' || encode-for-uri(path(.)) else null" ;
80+
rml:reference "if (exists(efbc:GroupFrameworkMaximumValueAmount)) then 'http://data.europa.eu/a4g/resource/id_' || replace(replace(/*/cbc:ID[@schemeName='notice-id'], ' ', '-' ), '/' , '-') || '_LotGroupAwardInformation_' || replace(replace(replace(path(.), 'Q\\{[^}]+\\}', ''), '\\[([0-9]+)\\]', '$1'), '/', '_') else null" ;
8181
rr:class epo:LotGroupAwardInformation
8282
] ;
8383
rr:predicateObjectMap

src/mappings-can/PaymentExecutor-can.rml.ttl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ tedm:MG-ContractTerm-isSubjectToContractSpecificTerm-Contract_ND-PayerParty a r
3636
[
3737
rdfs:label "ND-PayerParty" ;
3838
rdfs:comment "LotResultTechnicalIdentifier of MG-LotAwardOutcome under ND-LotResult" ;
39-
rml:reference "if (exists(../../efac:SettledContract/cbc:ID)) then 'http://data.europa.eu/a4g/resource/id_' || replace(replace(/*/cbc:ID[@schemeName='notice-id'], ' ', '-' ), '/' , '-') || '_ContractTerm_' || encode-for-uri(path()) else null" ;
39+
rml:reference "if (exists(../../efac:SettledContract/cbc:ID)) then 'http://data.europa.eu/a4g/resource/id_' || replace(replace(/*/cbc:ID[@schemeName='notice-id'], ' ', '-' ), '/' , '-') || '_ContractTerm_' || replace(replace(replace(path(), 'Q\\{[^}]+\\}', ''), '\\[([0-9]+)\\]', '$1'), '/', '_') else null" ;
4040
rr:class epo:ContractTerm
4141
] ;
4242
rr:predicateObjectMap

0 commit comments

Comments
 (0)