Skip to content

Commit 1862c64

Browse files
committed
added describerecord
1 parent 055c19a commit 1862c64

File tree

3 files changed

+140
-4
lines changed

3 files changed

+140
-4
lines changed

cswrequests.js

+10-4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { parseXml, evaluateXPath } from "./parsexml.js";
1+
import { parseXml, evaluateXPath, getDCMITerms } from "./parsexml.js";
22

33
const nodeValue = (nodes, index) => nodes[index] ? nodes[index].nodeValue : undefined;
44
const nodeArray = (nodes) => nodes?.length ? Array.from(nodes).map(node => node.nodeValue) : [];
@@ -88,15 +88,21 @@ export async function fetchDescribeRecord(url, cswVersion) {
8888

8989
const briefRecordTypeName = bareTypeName(nodeArray(evaluateXPath(cswDescribeRecord, '//xs:element[@name="BriefRecord"]/@type')));
9090
const briefRecordType = nodeArray(evaluateXPath(cswDescribeRecord, `//xs:complexType[@name="${briefRecordTypeName}"]/xs:complexContent/xs:extension/xs:sequence/xs:element/@ref`));
91-
const summaryRecordTypeName = bareTypeName(nodeArray(evaluateXPath(cswDescribeRecord, '//xs:element[@name="SummaryRecord"]/@type')))
91+
const summaryRecordTypeName = bareTypeName(nodeArray(evaluateXPath(cswDescribeRecord, '//xs:element[@name="SummaryRecord"]/@type')));
92+
const summaryRecordType = nodeArray(evaluateXPath(cswDescribeRecord, `//xs:complexType[@name="${summaryRecordTypeName}"]/xs:complexContent/xs:extension/xs:sequence/xs:element/@ref`));
9293
const recordTypeName = bareTypeName(nodeArray(evaluateXPath(cswDescribeRecord, '//xs:element[@name="Record"]/@type')));
94+
const recordType = nodeArray(evaluateXPath(cswDescribeRecord, `//xs:complexType[@name="${recordTypeName}"]/xs:complexContent/xs:extension/xs:sequence/xs:element/@ref`));
95+
const recordFields = recordType.map(field=>{return {name: field}});
96+
recordFields.push(...(await getDCMITerms()));
9397

9498
const summaryRecord = {
9599
cswVersion,
96-
recordTypes: nodeArray(evaluateXPath(cswDescribeRecord, '//csw:DescribeRecordResponse/csw:SchemaComponent/xs:schema/xs:element/@name')),
100+
//recordTypes: nodeArray(evaluateXPath(cswDescribeRecord, '//csw:DescribeRecordResponse/csw:SchemaComponent/xs:schema/xs:element/@name')),
97101
recordFields: nodeArray(evaluateXPath(cswDescribeRecord, '//xs:element[@name="Record"]/xs:complexType/xs:sequence/xs:element/@name')),
98102
summaryRecordFields: nodeArray(evaluateXPath(cswDescribeRecord, '//xs:element[@name="SummaryRecord"]/xs:complexType/xs:sequence/xs:element/@name')),
99-
briefRecordFields: briefRecordType
103+
briefRecordFields: briefRecordType.map(field=>{return {name: field}}),
104+
summaryRecordFields: summaryRecordType.map(field=>{return {name: field}}),
105+
recordFields
100106
};
101107

102108
return {

parsexml.js

+36
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import fs from 'fs';
12
// Define a variable to hold the appropriate DOMParser instance
23
let domParserPromise;
34
let xpath;
@@ -18,6 +19,41 @@ let xpath;
1819
}
1920
})();
2021

22+
async function loadXSD(filename) {
23+
while (!domParserPromise) {
24+
await new Promise(resolve => setTimeout(resolve, 100));
25+
}
26+
const DOMParserInstance = await domParserPromise;
27+
const data = fs.readFileSync(filename, 'utf8');
28+
const doc = DOMParserInstance.parseFromString(data, 'text/xml');
29+
return doc;
30+
}
31+
32+
async function loadAndParseXSDs() {
33+
try {
34+
//const dcmes = await loadXSD('rec-dcmes.xsd');
35+
const dcterms = await loadXSD('rec-dcterms.xsd');
36+
// Now you have the parsed XSDs as DOM documents.
37+
// You can start extracting field definitions from here.
38+
// For example, to get all 'element' nodes in the 'dcmes' document:
39+
const select = xpath.useNamespaces({ xs: 'http://www.w3.org/2001/XMLSchema' });
40+
const elements = select('//descendant-or-self::xs:element', dcterms);
41+
const fieldNames = elements.map((element) => {
42+
const name = element.getAttribute('name');
43+
const substitutionGroup = element.getAttribute('substitutionGroup');
44+
return { name: name !== ''? 'dct:'+ name : '', substitutionGroup };
45+
}).filter((element)=>element.name !== '');
46+
return fieldNames
47+
} catch (err) {
48+
console.error(err);
49+
return [];
50+
}
51+
}
52+
53+
export const getDCMITerms = async () => {
54+
return loadAndParseXSDs();
55+
}
56+
2157
// Function to parse XML with the pre-initialized DOMParser
2258
export const parseXml = async (xmlString) => {
2359
const DOMParserInstance = await domParserPromise;

rec-dcterms.xsd

+94
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
<?xml version="1.0" encoding="ISO-8859-1"?>
2+
<xs:schema id="dcmi-terms" targetNamespace="http://purl.org/dc/terms/"
3+
xmlns:xs="http://www.w3.org/2001/XMLSchema"
4+
xmlns:dct="http://purl.org/dc/terms/"
5+
xmlns:dc="http://purl.org/dc/elements/1.1/" elementFormDefault="qualified"
6+
attributeFormDefault="unqualified" version="2.0.2.2">
7+
<xs:annotation>
8+
<xs:documentation xml:lang="en"
9+
source="http://dublincore.org/documents/dcmi-terms/">This schema declares additional DCMI elements and element refinements
10+
in the "http://purl.org/dc/terms/" namespace.</xs:documentation>
11+
</xs:annotation>
12+
<xs:import namespace="http://purl.org/dc/elements/1.1/" schemaLocation="http://schemas.opengis.net/csw/2.0.2/rec-dcmes.xsd"/>
13+
<xs:element name="abstract" type="dc:SimpleLiteral"
14+
substitutionGroup="dc:description"/>
15+
<xs:element name="accessRights" type="dc:SimpleLiteral"
16+
substitutionGroup="dc:rights"/>
17+
<xs:element name="alternative" type="dc:SimpleLiteral"
18+
substitutionGroup="dc:title"/>
19+
<xs:element name="audience" type="dc:SimpleLiteral"
20+
substitutionGroup="dc:DC-element"/>
21+
<xs:element name="available" type="dc:SimpleLiteral"
22+
substitutionGroup="dc:date"/>
23+
<xs:element name="bibliographicCitation" type="dc:SimpleLiteral"
24+
substitutionGroup="dc:identifier"/>
25+
<xs:element name="conformsTo" type="dc:SimpleLiteral"
26+
substitutionGroup="dc:relation"/>
27+
<xs:element name="created" type="dc:SimpleLiteral"
28+
substitutionGroup="dc:date"/>
29+
<xs:element name="dateAccepted" type="dc:SimpleLiteral"
30+
substitutionGroup="dc:date"/>
31+
<xs:element name="dateCopyrighted" type="dc:SimpleLiteral"
32+
substitutionGroup="dc:date"/>
33+
<xs:element name="dateSubmitted" type="dc:SimpleLiteral"
34+
substitutionGroup="dc:date"/>
35+
<xs:element name="educationLevel" type="dc:SimpleLiteral"
36+
substitutionGroup="dct:audience"/>
37+
<xs:element name="extent" type="dc:SimpleLiteral"
38+
substitutionGroup="dc:format"/>
39+
<xs:element name="hasFormat" type="dc:SimpleLiteral"
40+
substitutionGroup="dc:relation"/>
41+
<xs:element name="hasPart" type="dc:SimpleLiteral"
42+
substitutionGroup="dc:relation"/>
43+
<xs:element name="hasVersion" type="dc:SimpleLiteral"
44+
substitutionGroup="dc:relation"/>
45+
<xs:element name="isFormatOf" type="dc:SimpleLiteral"
46+
substitutionGroup="dc:relation"/>
47+
<xs:element name="isPartOf" type="dc:SimpleLiteral"
48+
substitutionGroup="dc:relation"/>
49+
<xs:element name="isReferencedBy" type="dc:SimpleLiteral"
50+
substitutionGroup="dc:relation"/>
51+
<xs:element name="isReplacedBy" type="dc:SimpleLiteral"
52+
substitutionGroup="dc:relation"/>
53+
<xs:element name="isRequiredBy" type="dc:SimpleLiteral"
54+
substitutionGroup="dc:relation"/>
55+
<xs:element name="issued" type="dc:SimpleLiteral" substitutionGroup="dc:date"/>
56+
<xs:element name="isVersionOf" type="dc:SimpleLiteral"
57+
substitutionGroup="dc:relation"/>
58+
<xs:element name="license" type="dc:SimpleLiteral"
59+
substitutionGroup="dc:rights"/>
60+
<xs:element name="mediator" type="dc:SimpleLiteral"
61+
substitutionGroup="dct:audience"/>
62+
<xs:element name="medium" type="dc:SimpleLiteral"
63+
substitutionGroup="dc:format"/>
64+
<xs:element name="modified" type="dc:SimpleLiteral"
65+
substitutionGroup="dc:date"/>
66+
<xs:element name="provenance" type="dc:SimpleLiteral"
67+
substitutionGroup="dc:DC-element"/>
68+
<xs:element name="references" type="dc:SimpleLiteral"
69+
substitutionGroup="dc:relation"/>
70+
<xs:element name="replaces" type="dc:SimpleLiteral"
71+
substitutionGroup="dc:relation"/>
72+
<xs:element name="requires" type="dc:SimpleLiteral"
73+
substitutionGroup="dc:relation"/>
74+
<xs:element name="rightsHolder" type="dc:SimpleLiteral"
75+
substitutionGroup="dc:DC-element"/>
76+
<xs:element name="spatial" type="dc:SimpleLiteral"
77+
substitutionGroup="dc:coverage"/>
78+
<xs:element name="tableOfContents" type="dc:SimpleLiteral"
79+
substitutionGroup="dc:description"/>
80+
<xs:element name="temporal" type="dc:SimpleLiteral"
81+
substitutionGroup="dc:coverage"/>
82+
<xs:element name="valid" type="dc:SimpleLiteral" substitutionGroup="dc:date"/>
83+
<xs:group name="DCMI-terms">
84+
<xs:annotation>
85+
<xs:documentation xml:lang="en">This group is included as a convenience for schema authors who need
86+
to refer to the complete set of DCMI metadata terms.</xs:documentation>
87+
</xs:annotation>
88+
<xs:sequence>
89+
<xs:choice minOccurs="0" maxOccurs="unbounded">
90+
<xs:element ref="dc:DC-element"/>
91+
</xs:choice>
92+
</xs:sequence>
93+
</xs:group>
94+
</xs:schema>

0 commit comments

Comments
 (0)