dsp-tools 0.9.13__py3-none-any.whl → 18.3.0.post13__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- dsp_tools/__init__.py +5 -0
- dsp_tools/cli/args.py +47 -0
- dsp_tools/cli/call_action.py +85 -0
- dsp_tools/cli/call_action_files_only.py +101 -0
- dsp_tools/cli/call_action_with_network.py +207 -0
- dsp_tools/cli/create_parsers.py +479 -0
- dsp_tools/cli/entry_point.py +322 -0
- dsp_tools/cli/utils.py +87 -0
- dsp_tools/clients/CLAUDE.md +420 -0
- dsp_tools/clients/authentication_client.py +14 -0
- dsp_tools/clients/authentication_client_live.py +66 -0
- dsp_tools/clients/connection.py +35 -0
- dsp_tools/clients/connection_live.py +233 -0
- dsp_tools/clients/fuseki_metrics.py +60 -0
- dsp_tools/clients/group_user_clients.py +35 -0
- dsp_tools/clients/group_user_clients_live.py +181 -0
- dsp_tools/clients/legal_info_client.py +23 -0
- dsp_tools/clients/legal_info_client_live.py +132 -0
- dsp_tools/clients/list_client.py +49 -0
- dsp_tools/clients/list_client_live.py +166 -0
- dsp_tools/clients/metadata_client.py +24 -0
- dsp_tools/clients/metadata_client_live.py +47 -0
- dsp_tools/clients/ontology_clients.py +49 -0
- dsp_tools/clients/ontology_create_client_live.py +166 -0
- dsp_tools/clients/ontology_get_client_live.py +80 -0
- dsp_tools/clients/permissions_client.py +68 -0
- dsp_tools/clients/project_client.py +16 -0
- dsp_tools/clients/project_client_live.py +66 -0
- dsp_tools/commands/create/communicate_problems.py +24 -0
- dsp_tools/commands/create/create.py +134 -0
- dsp_tools/commands/create/create_on_server/cardinalities.py +111 -0
- dsp_tools/commands/create/create_on_server/classes.py +99 -0
- dsp_tools/commands/create/create_on_server/complete_ontologies.py +116 -0
- dsp_tools/commands/create/create_on_server/default_permissions.py +134 -0
- dsp_tools/commands/create/create_on_server/group_users.py +165 -0
- dsp_tools/commands/create/create_on_server/lists.py +163 -0
- dsp_tools/commands/create/create_on_server/mappers.py +12 -0
- dsp_tools/commands/create/create_on_server/onto_utils.py +74 -0
- dsp_tools/commands/create/create_on_server/ontology.py +52 -0
- dsp_tools/commands/create/create_on_server/project.py +68 -0
- dsp_tools/commands/create/create_on_server/properties.py +119 -0
- dsp_tools/commands/create/exceptions.py +29 -0
- dsp_tools/commands/create/lists_only.py +66 -0
- dsp_tools/commands/create/models/create_problems.py +87 -0
- dsp_tools/commands/create/models/parsed_ontology.py +88 -0
- dsp_tools/commands/create/models/parsed_project.py +81 -0
- dsp_tools/commands/create/models/rdf_ontology.py +12 -0
- dsp_tools/commands/create/models/server_project_info.py +100 -0
- dsp_tools/commands/create/parsing/parse_lists.py +45 -0
- dsp_tools/commands/create/parsing/parse_ontology.py +243 -0
- dsp_tools/commands/create/parsing/parse_project.py +149 -0
- dsp_tools/commands/create/parsing/parsing_utils.py +40 -0
- dsp_tools/commands/create/project_validate.py +595 -0
- dsp_tools/commands/create/serialisation/ontology.py +119 -0
- dsp_tools/commands/create/serialisation/project.py +44 -0
- dsp_tools/commands/excel2json/CLAUDE.md +101 -0
- dsp_tools/commands/excel2json/json_header.py +321 -0
- dsp_tools/commands/excel2json/lists/__init__.py +0 -0
- dsp_tools/commands/excel2json/lists/compliance_checks.py +292 -0
- dsp_tools/commands/excel2json/lists/make_lists.py +247 -0
- dsp_tools/commands/excel2json/lists/models/__init__.py +0 -0
- dsp_tools/commands/excel2json/lists/models/deserialise.py +30 -0
- dsp_tools/commands/excel2json/lists/models/input_error.py +216 -0
- dsp_tools/commands/excel2json/lists/models/serialise.py +57 -0
- dsp_tools/commands/excel2json/lists/utils.py +81 -0
- dsp_tools/commands/excel2json/models/__init__.py +0 -0
- dsp_tools/commands/excel2json/models/input_error.py +416 -0
- dsp_tools/commands/excel2json/models/json_header.py +175 -0
- dsp_tools/commands/excel2json/models/list_node_name.py +16 -0
- dsp_tools/commands/excel2json/models/ontology.py +76 -0
- dsp_tools/commands/excel2json/old_lists.py +328 -0
- dsp_tools/commands/excel2json/project.py +280 -0
- dsp_tools/commands/excel2json/properties.py +370 -0
- dsp_tools/commands/excel2json/resources.py +336 -0
- dsp_tools/commands/excel2json/utils.py +352 -0
- dsp_tools/commands/excel2xml/__init__.py +7 -0
- dsp_tools/commands/excel2xml/excel2xml_cli.py +523 -0
- dsp_tools/commands/excel2xml/excel2xml_lib.py +1953 -0
- dsp_tools/commands/excel2xml/propertyelement.py +47 -0
- dsp_tools/commands/get/__init__.py +0 -0
- dsp_tools/commands/get/get.py +166 -0
- dsp_tools/commands/get/get_permissions.py +257 -0
- dsp_tools/commands/get/get_permissions_legacy.py +89 -0
- dsp_tools/commands/get/legacy_models/__init__.py +0 -0
- dsp_tools/commands/get/legacy_models/context.py +318 -0
- dsp_tools/commands/get/legacy_models/group.py +241 -0
- dsp_tools/commands/get/legacy_models/helpers.py +47 -0
- dsp_tools/commands/get/legacy_models/listnode.py +390 -0
- dsp_tools/commands/get/legacy_models/model.py +12 -0
- dsp_tools/commands/get/legacy_models/ontology.py +324 -0
- dsp_tools/commands/get/legacy_models/project.py +366 -0
- dsp_tools/commands/get/legacy_models/propertyclass.py +417 -0
- dsp_tools/commands/get/legacy_models/resourceclass.py +676 -0
- dsp_tools/commands/get/legacy_models/user.py +438 -0
- dsp_tools/commands/get/models/__init__.py +0 -0
- dsp_tools/commands/get/models/permissions_models.py +10 -0
- dsp_tools/commands/id2iri.py +258 -0
- dsp_tools/commands/ingest_xmlupload/__init__.py +0 -0
- dsp_tools/commands/ingest_xmlupload/bulk_ingest_client.py +178 -0
- dsp_tools/commands/ingest_xmlupload/create_resources/__init__.py +0 -0
- dsp_tools/commands/ingest_xmlupload/create_resources/apply_ingest_id.py +69 -0
- dsp_tools/commands/ingest_xmlupload/create_resources/upload_xml.py +166 -0
- dsp_tools/commands/ingest_xmlupload/create_resources/user_information.py +121 -0
- dsp_tools/commands/ingest_xmlupload/ingest_files/__init__.py +0 -0
- dsp_tools/commands/ingest_xmlupload/ingest_files/ingest_files.py +64 -0
- dsp_tools/commands/ingest_xmlupload/upload_files/__init__.py +0 -0
- dsp_tools/commands/ingest_xmlupload/upload_files/filechecker.py +20 -0
- dsp_tools/commands/ingest_xmlupload/upload_files/input_error.py +57 -0
- dsp_tools/commands/ingest_xmlupload/upload_files/upload_failures.py +66 -0
- dsp_tools/commands/ingest_xmlupload/upload_files/upload_files.py +67 -0
- dsp_tools/commands/resume_xmlupload/__init__.py +0 -0
- dsp_tools/commands/resume_xmlupload/resume_xmlupload.py +96 -0
- dsp_tools/commands/start_stack.py +428 -0
- dsp_tools/commands/update_legal/CLAUDE.md +344 -0
- dsp_tools/commands/update_legal/__init__.py +0 -0
- dsp_tools/commands/update_legal/core.py +182 -0
- dsp_tools/commands/update_legal/csv_operations.py +135 -0
- dsp_tools/commands/update_legal/models.py +87 -0
- dsp_tools/commands/update_legal/xml_operations.py +247 -0
- dsp_tools/commands/validate_data/CLAUDE.md +159 -0
- dsp_tools/commands/validate_data/__init__.py +0 -0
- dsp_tools/commands/validate_data/constants.py +59 -0
- dsp_tools/commands/validate_data/mappers.py +143 -0
- dsp_tools/commands/validate_data/models/__init__.py +0 -0
- dsp_tools/commands/validate_data/models/api_responses.py +45 -0
- dsp_tools/commands/validate_data/models/input_problems.py +119 -0
- dsp_tools/commands/validate_data/models/rdf_like_data.py +117 -0
- dsp_tools/commands/validate_data/models/validation.py +106 -0
- dsp_tools/commands/validate_data/prepare_data/__init__.py +0 -0
- dsp_tools/commands/validate_data/prepare_data/get_rdf_like_data.py +296 -0
- dsp_tools/commands/validate_data/prepare_data/make_data_graph.py +91 -0
- dsp_tools/commands/validate_data/prepare_data/prepare_data.py +184 -0
- dsp_tools/commands/validate_data/process_validation_report/__init__.py +0 -0
- dsp_tools/commands/validate_data/process_validation_report/get_user_validation_message.py +358 -0
- dsp_tools/commands/validate_data/process_validation_report/query_validation_result.py +507 -0
- dsp_tools/commands/validate_data/process_validation_report/reformat_validation_results.py +150 -0
- dsp_tools/commands/validate_data/shacl_cli_validator.py +70 -0
- dsp_tools/commands/validate_data/sparql/__init__.py +0 -0
- dsp_tools/commands/validate_data/sparql/cardinality_shacl.py +209 -0
- dsp_tools/commands/validate_data/sparql/construct_shacl.py +92 -0
- dsp_tools/commands/validate_data/sparql/legal_info_shacl.py +36 -0
- dsp_tools/commands/validate_data/sparql/value_shacl.py +357 -0
- dsp_tools/commands/validate_data/utils.py +59 -0
- dsp_tools/commands/validate_data/validate_data.py +283 -0
- dsp_tools/commands/validate_data/validation/__init__.py +0 -0
- dsp_tools/commands/validate_data/validation/check_duplicate_files.py +55 -0
- dsp_tools/commands/validate_data/validation/check_for_unknown_classes.py +67 -0
- dsp_tools/commands/validate_data/validation/get_validation_report.py +94 -0
- dsp_tools/commands/validate_data/validation/validate_ontology.py +107 -0
- dsp_tools/commands/xmlupload/CLAUDE.md +292 -0
- dsp_tools/commands/xmlupload/__init__.py +0 -0
- dsp_tools/commands/xmlupload/iri_resolver.py +21 -0
- dsp_tools/commands/xmlupload/make_rdf_graph/__init__.py +0 -0
- dsp_tools/commands/xmlupload/make_rdf_graph/constants.py +63 -0
- dsp_tools/commands/xmlupload/make_rdf_graph/jsonld_utils.py +44 -0
- dsp_tools/commands/xmlupload/make_rdf_graph/make_file_value.py +77 -0
- dsp_tools/commands/xmlupload/make_rdf_graph/make_resource_and_values.py +114 -0
- dsp_tools/commands/xmlupload/make_rdf_graph/make_values.py +262 -0
- dsp_tools/commands/xmlupload/models/__init__.py +0 -0
- dsp_tools/commands/xmlupload/models/bitstream_info.py +18 -0
- dsp_tools/commands/xmlupload/models/formatted_text_value.py +10 -0
- dsp_tools/commands/xmlupload/models/ingest.py +143 -0
- dsp_tools/commands/xmlupload/models/input_problems.py +58 -0
- dsp_tools/commands/xmlupload/models/lookup_models.py +21 -0
- dsp_tools/commands/xmlupload/models/permission.py +45 -0
- dsp_tools/commands/xmlupload/models/permissions_parsed.py +93 -0
- dsp_tools/commands/xmlupload/models/processed/__init__.py +0 -0
- dsp_tools/commands/xmlupload/models/processed/file_values.py +29 -0
- dsp_tools/commands/xmlupload/models/processed/res.py +27 -0
- dsp_tools/commands/xmlupload/models/processed/values.py +101 -0
- dsp_tools/commands/xmlupload/models/rdf_models.py +26 -0
- dsp_tools/commands/xmlupload/models/upload_clients.py +14 -0
- dsp_tools/commands/xmlupload/models/upload_state.py +20 -0
- dsp_tools/commands/xmlupload/prepare_xml_input/__init__.py +0 -0
- dsp_tools/commands/xmlupload/prepare_xml_input/ark2iri.py +55 -0
- dsp_tools/commands/xmlupload/prepare_xml_input/get_processed_resources.py +252 -0
- dsp_tools/commands/xmlupload/prepare_xml_input/iiif_uri_validator.py +50 -0
- dsp_tools/commands/xmlupload/prepare_xml_input/list_client.py +120 -0
- dsp_tools/commands/xmlupload/prepare_xml_input/prepare_xml_input.py +67 -0
- dsp_tools/commands/xmlupload/prepare_xml_input/read_validate_xml_file.py +58 -0
- dsp_tools/commands/xmlupload/prepare_xml_input/transform_input_values.py +118 -0
- dsp_tools/commands/xmlupload/resource_create_client.py +25 -0
- dsp_tools/commands/xmlupload/richtext_id2iri.py +37 -0
- dsp_tools/commands/xmlupload/stash/__init__.py +0 -0
- dsp_tools/commands/xmlupload/stash/analyse_circular_reference_graph.py +236 -0
- dsp_tools/commands/xmlupload/stash/create_info_for_graph.py +53 -0
- dsp_tools/commands/xmlupload/stash/graph_models.py +87 -0
- dsp_tools/commands/xmlupload/stash/stash_circular_references.py +68 -0
- dsp_tools/commands/xmlupload/stash/stash_models.py +109 -0
- dsp_tools/commands/xmlupload/stash/upload_stashed_resptr_props.py +106 -0
- dsp_tools/commands/xmlupload/stash/upload_stashed_xml_texts.py +196 -0
- dsp_tools/commands/xmlupload/upload_config.py +76 -0
- dsp_tools/commands/xmlupload/write_diagnostic_info.py +27 -0
- dsp_tools/commands/xmlupload/xmlupload.py +516 -0
- dsp_tools/config/__init__.py +0 -0
- dsp_tools/config/logger_config.py +69 -0
- dsp_tools/config/warnings_config.py +32 -0
- dsp_tools/error/__init__.py +0 -0
- dsp_tools/error/custom_warnings.py +39 -0
- dsp_tools/error/exceptions.py +204 -0
- dsp_tools/error/problems.py +10 -0
- dsp_tools/error/xmllib_errors.py +20 -0
- dsp_tools/error/xmllib_warnings.py +54 -0
- dsp_tools/error/xmllib_warnings_util.py +159 -0
- dsp_tools/error/xsd_validation_error_msg.py +19 -0
- dsp_tools/legacy_models/__init__.py +0 -0
- dsp_tools/legacy_models/datetimestamp.py +81 -0
- dsp_tools/legacy_models/langstring.py +253 -0
- dsp_tools/legacy_models/projectContext.py +49 -0
- dsp_tools/py.typed +0 -0
- dsp_tools/resources/schema/data.xsd +648 -0
- dsp_tools/resources/schema/lists-only.json +72 -0
- dsp_tools/resources/schema/project.json +1258 -0
- dsp_tools/resources/schema/properties-only.json +874 -0
- dsp_tools/resources/schema/resources-only.json +140 -0
- dsp_tools/resources/start-stack/docker-compose.override-host.j2 +11 -0
- dsp_tools/resources/start-stack/docker-compose.override.yml +11 -0
- dsp_tools/resources/start-stack/docker-compose.yml +88 -0
- dsp_tools/resources/start-stack/dsp-app-config.json +45 -0
- dsp_tools/resources/start-stack/dsp-app-config.override-host.j2 +26 -0
- dsp_tools/resources/validate_data/api-shapes-resource-cardinalities.ttl +191 -0
- dsp_tools/resources/validate_data/api-shapes.ttl +804 -0
- dsp_tools/resources/validate_data/shacl-cli-image.yml +4 -0
- dsp_tools/resources/validate_data/validate-ontology.ttl +99 -0
- dsp_tools/utils/__init__.py +0 -0
- dsp_tools/utils/ansi_colors.py +32 -0
- dsp_tools/utils/data_formats/__init__.py +0 -0
- dsp_tools/utils/data_formats/date_util.py +166 -0
- dsp_tools/utils/data_formats/iri_util.py +30 -0
- dsp_tools/utils/data_formats/shared.py +81 -0
- dsp_tools/utils/data_formats/uri_util.py +76 -0
- dsp_tools/utils/fuseki_bloating.py +63 -0
- dsp_tools/utils/json_parsing.py +22 -0
- dsp_tools/utils/rdf_constants.py +42 -0
- dsp_tools/utils/rdflib_utils.py +10 -0
- dsp_tools/utils/replace_id_with_iri.py +66 -0
- dsp_tools/utils/request_utils.py +238 -0
- dsp_tools/utils/xml_parsing/__init__.py +0 -0
- dsp_tools/utils/xml_parsing/get_lookups.py +32 -0
- dsp_tools/utils/xml_parsing/get_parsed_resources.py +325 -0
- dsp_tools/utils/xml_parsing/models/__init__.py +0 -0
- dsp_tools/utils/xml_parsing/models/parsed_resource.py +76 -0
- dsp_tools/utils/xml_parsing/parse_clean_validate_xml.py +137 -0
- dsp_tools/xmllib/CLAUDE.md +302 -0
- dsp_tools/xmllib/__init__.py +49 -0
- dsp_tools/xmllib/general_functions.py +877 -0
- dsp_tools/xmllib/internal/__init__.py +0 -0
- dsp_tools/xmllib/internal/checkers.py +162 -0
- dsp_tools/xmllib/internal/circumvent_circular_imports.py +36 -0
- dsp_tools/xmllib/internal/constants.py +46 -0
- dsp_tools/xmllib/internal/input_converters.py +155 -0
- dsp_tools/xmllib/internal/serialise_file_value.py +57 -0
- dsp_tools/xmllib/internal/serialise_resource.py +177 -0
- dsp_tools/xmllib/internal/serialise_values.py +152 -0
- dsp_tools/xmllib/internal/type_aliases.py +11 -0
- dsp_tools/xmllib/models/__init__.py +0 -0
- dsp_tools/xmllib/models/config_options.py +28 -0
- dsp_tools/xmllib/models/date_formats.py +48 -0
- dsp_tools/xmllib/models/dsp_base_resources.py +1542 -0
- dsp_tools/xmllib/models/internal/__init__.py +0 -0
- dsp_tools/xmllib/models/internal/file_values.py +172 -0
- dsp_tools/xmllib/models/internal/geometry.py +162 -0
- dsp_tools/xmllib/models/internal/migration_metadata.py +55 -0
- dsp_tools/xmllib/models/internal/serialise_permissions.py +66 -0
- dsp_tools/xmllib/models/internal/values.py +342 -0
- dsp_tools/xmllib/models/licenses/__init__.py +0 -0
- dsp_tools/xmllib/models/licenses/other.py +59 -0
- dsp_tools/xmllib/models/licenses/recommended.py +107 -0
- dsp_tools/xmllib/models/permissions.py +41 -0
- dsp_tools/xmllib/models/res.py +1782 -0
- dsp_tools/xmllib/models/root.py +348 -0
- dsp_tools/xmllib/value_checkers.py +434 -0
- dsp_tools/xmllib/value_converters.py +777 -0
- dsp_tools-18.3.0.post13.dist-info/METADATA +90 -0
- dsp_tools-18.3.0.post13.dist-info/RECORD +286 -0
- dsp_tools-18.3.0.post13.dist-info/WHEEL +4 -0
- dsp_tools-18.3.0.post13.dist-info/entry_points.txt +3 -0
- dsp_tools-0.9.13.dist-info/LICENSE +0 -674
- dsp_tools-0.9.13.dist-info/METADATA +0 -144
- dsp_tools-0.9.13.dist-info/RECORD +0 -71
- dsp_tools-0.9.13.dist-info/WHEEL +0 -5
- dsp_tools-0.9.13.dist-info/entry_points.txt +0 -3
- dsp_tools-0.9.13.dist-info/top_level.txt +0 -1
- dsplib/models/connection.py +0 -272
- dsplib/models/group.py +0 -296
- dsplib/models/helpers.py +0 -505
- dsplib/models/langstring.py +0 -277
- dsplib/models/listnode.py +0 -578
- dsplib/models/model.py +0 -20
- dsplib/models/ontology.py +0 -448
- dsplib/models/permission.py +0 -112
- dsplib/models/project.py +0 -547
- dsplib/models/propertyclass.py +0 -505
- dsplib/models/resource.py +0 -366
- dsplib/models/resourceclass.py +0 -810
- dsplib/models/sipi.py +0 -30
- dsplib/models/user.py +0 -731
- dsplib/models/value.py +0 -1000
- dsplib/utils/knora-data-schema.xsd +0 -454
- dsplib/utils/knora-schema-lists.json +0 -83
- dsplib/utils/knora-schema.json +0 -434
- dsplib/utils/onto_commons.py +0 -24
- dsplib/utils/onto_create_lists.py +0 -73
- dsplib/utils/onto_create_ontology.py +0 -442
- dsplib/utils/onto_get.py +0 -58
- dsplib/utils/onto_validate.py +0 -33
- dsplib/utils/xml_upload.py +0 -539
- dsplib/widgets/doublepassword.py +0 -80
- knora/MLS-import-libraries.py +0 -84
- knora/dsp_tools.py +0 -96
- knora/dsplib/models/connection.py +0 -272
- knora/dsplib/models/group.py +0 -296
- knora/dsplib/models/helpers.py +0 -506
- knora/dsplib/models/langstring.py +0 -277
- knora/dsplib/models/listnode.py +0 -578
- knora/dsplib/models/model.py +0 -20
- knora/dsplib/models/ontology.py +0 -448
- knora/dsplib/models/permission.py +0 -112
- knora/dsplib/models/project.py +0 -583
- knora/dsplib/models/propertyclass.py +0 -505
- knora/dsplib/models/resource.py +0 -416
- knora/dsplib/models/resourceclass.py +0 -811
- knora/dsplib/models/sipi.py +0 -35
- knora/dsplib/models/user.py +0 -731
- knora/dsplib/models/value.py +0 -1000
- knora/dsplib/utils/knora-data-schema.xsd +0 -464
- knora/dsplib/utils/knora-schema-lists.json +0 -83
- knora/dsplib/utils/knora-schema.json +0 -444
- knora/dsplib/utils/onto_commons.py +0 -24
- knora/dsplib/utils/onto_create_lists.py +0 -73
- knora/dsplib/utils/onto_create_ontology.py +0 -451
- knora/dsplib/utils/onto_get.py +0 -58
- knora/dsplib/utils/onto_validate.py +0 -33
- knora/dsplib/utils/xml_upload.py +0 -540
- knora/dsplib/widgets/doublepassword.py +0 -80
- knora/knora.py +0 -2108
- knora/test.py +0 -99
- knora/testit.py +0 -76
- knora/xml2knora.py +0 -633
- {dsplib → dsp_tools/cli}/__init__.py +0 -0
- {dsplib/models → dsp_tools/clients}/__init__.py +0 -0
- {dsplib/utils → dsp_tools/commands}/__init__.py +0 -0
- {dsplib/widgets → dsp_tools/commands/create}/__init__.py +0 -0
- {knora → dsp_tools/commands/create/create_on_server}/__init__.py +0 -0
- {knora/dsplib → dsp_tools/commands/create/models}/__init__.py +0 -0
- {knora/dsplib/models → dsp_tools/commands/create/parsing}/__init__.py +0 -0
- {knora/dsplib/utils → dsp_tools/commands/create/serialisation}/__init__.py +0 -0
- {knora/dsplib/widgets → dsp_tools/commands/excel2json}/__init__.py +0 -0
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from dataclasses import dataclass
|
|
4
|
+
from enum import Enum
|
|
5
|
+
from enum import auto
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
@dataclass
|
|
9
|
+
class ParsedResource:
|
|
10
|
+
res_id: str
|
|
11
|
+
res_type: str
|
|
12
|
+
label: str
|
|
13
|
+
permissions_id: str | None
|
|
14
|
+
values: list[ParsedValue]
|
|
15
|
+
file_value: ParsedFileValue | None
|
|
16
|
+
migration_metadata: ParsedMigrationMetadata | None
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
@dataclass
|
|
20
|
+
class ParsedMigrationMetadata:
|
|
21
|
+
iri: str | None
|
|
22
|
+
ark: str | None
|
|
23
|
+
creation_date: str | None
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
@dataclass
|
|
27
|
+
class ParsedValue:
|
|
28
|
+
prop_name: str
|
|
29
|
+
value: str | tuple[str | None, str | None] | None
|
|
30
|
+
value_type: KnoraValueType
|
|
31
|
+
permissions_id: str | None
|
|
32
|
+
comment: str | None
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
@dataclass
|
|
36
|
+
class ParsedFileValue:
|
|
37
|
+
value: str | None
|
|
38
|
+
value_type: KnoraValueType | None
|
|
39
|
+
metadata: ParsedFileValueMetadata
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
@dataclass
|
|
43
|
+
class ParsedFileValueMetadata:
|
|
44
|
+
license_iri: str | None
|
|
45
|
+
copyright_holder: str | None
|
|
46
|
+
authorship_id: str | None
|
|
47
|
+
permissions_id: str | None
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
class KnoraValueType(Enum):
|
|
51
|
+
"""
|
|
52
|
+
Maps to a knora value type, for example: BOOLEAN_VALUE -> knora-api:BooleanValue
|
|
53
|
+
"""
|
|
54
|
+
|
|
55
|
+
BOOLEAN_VALUE = auto()
|
|
56
|
+
COLOR_VALUE = auto()
|
|
57
|
+
DATE_VALUE = auto()
|
|
58
|
+
DECIMAL_VALUE = auto()
|
|
59
|
+
GEONAME_VALUE = auto()
|
|
60
|
+
GEOM_VALUE = auto()
|
|
61
|
+
INT_VALUE = auto()
|
|
62
|
+
INTERVAL_VALUE = auto()
|
|
63
|
+
LINK_VALUE = auto()
|
|
64
|
+
LIST_VALUE = auto()
|
|
65
|
+
SIMPLETEXT_VALUE = auto()
|
|
66
|
+
RICHTEXT_VALUE = auto()
|
|
67
|
+
TIME_VALUE = auto()
|
|
68
|
+
URI_VALUE = auto()
|
|
69
|
+
|
|
70
|
+
ARCHIVE_FILE = auto()
|
|
71
|
+
AUDIO_FILE = auto()
|
|
72
|
+
DOCUMENT_FILE = auto()
|
|
73
|
+
MOVING_IMAGE_FILE = auto()
|
|
74
|
+
STILL_IMAGE_FILE = auto()
|
|
75
|
+
STILL_IMAGE_IIIF = auto()
|
|
76
|
+
TEXT_FILE = auto()
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import importlib.resources
|
|
4
|
+
from copy import deepcopy
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
|
|
7
|
+
import pandas as pd
|
|
8
|
+
import regex
|
|
9
|
+
from loguru import logger
|
|
10
|
+
from lxml import etree
|
|
11
|
+
|
|
12
|
+
from dsp_tools.error.exceptions import InputError
|
|
13
|
+
from dsp_tools.error.exceptions import UserFilepathNotFoundError
|
|
14
|
+
from dsp_tools.error.xsd_validation_error_msg import XSDValidationMessage
|
|
15
|
+
from dsp_tools.error.xsd_validation_error_msg import get_xsd_validation_message_str
|
|
16
|
+
from dsp_tools.utils.ansi_colors import BACKGROUND_BOLD_RED
|
|
17
|
+
from dsp_tools.utils.ansi_colors import BOLD_RED
|
|
18
|
+
from dsp_tools.utils.ansi_colors import RESET_TO_DEFAULT
|
|
19
|
+
|
|
20
|
+
separator = "\n "
|
|
21
|
+
list_separator = "\n - "
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def parse_and_clean_xml_file(input_file: Path) -> etree._Element:
|
|
25
|
+
root = parse_xml_file(input_file)
|
|
26
|
+
root = _remove_comments_from_element_tree(root)
|
|
27
|
+
if not validate_root_emit_user_message(root, Path(input_file).parent):
|
|
28
|
+
raise InputError("The XML file contains validation errors.") # a detailed report has already been printed
|
|
29
|
+
print("The XML file is syntactically correct.")
|
|
30
|
+
return transform_into_localnames(root)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def parse_and_validate_xml_file(input_file: Path | str) -> bool:
|
|
34
|
+
root = parse_xml_file(input_file)
|
|
35
|
+
data_xml = _remove_comments_from_element_tree(root)
|
|
36
|
+
return validate_root_emit_user_message(data_xml, Path(input_file).parent)
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def parse_xml_file(input_file: str | Path) -> etree._Element:
|
|
40
|
+
parser = etree.XMLParser(remove_comments=True, remove_pis=True)
|
|
41
|
+
if not Path(input_file).exists():
|
|
42
|
+
raise UserFilepathNotFoundError(input_file)
|
|
43
|
+
try:
|
|
44
|
+
return etree.parse(source=input_file, parser=parser).getroot()
|
|
45
|
+
except etree.XMLSyntaxError as err:
|
|
46
|
+
logger.error(f"The XML file contains the following syntax error: {err.msg}")
|
|
47
|
+
raise InputError(f"The XML file contains the following syntax error: {err.msg}") from None
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def transform_into_localnames(root: etree._Element) -> etree._Element:
|
|
51
|
+
"""Removes the namespace of the tags."""
|
|
52
|
+
tree = deepcopy(root)
|
|
53
|
+
for elem in tree.iter():
|
|
54
|
+
elem.tag = etree.QName(elem).localname
|
|
55
|
+
return tree
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def _remove_comments_from_element_tree(input_tree: etree._Element) -> etree._Element:
|
|
59
|
+
"""Removes comments and processing instructions."""
|
|
60
|
+
root = deepcopy(input_tree)
|
|
61
|
+
for c in root.xpath("//comment()"):
|
|
62
|
+
c.getparent().remove(c)
|
|
63
|
+
for c in root.xpath("//processing-instruction()"):
|
|
64
|
+
c.getparent().remove(c)
|
|
65
|
+
return root
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def _validate_xml_tree_against_schema(data_xml: etree._Element) -> etree.XMLSchema | None:
|
|
69
|
+
schema_res = importlib.resources.files("dsp_tools").joinpath("resources/schema/data.xsd")
|
|
70
|
+
with schema_res.open(encoding="utf-8") as schema_file:
|
|
71
|
+
xmlschema = etree.XMLSchema(etree.parse(schema_file))
|
|
72
|
+
if not xmlschema.validate(data_xml):
|
|
73
|
+
return xmlschema
|
|
74
|
+
return None
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
def validate_root_emit_user_message(root: etree._Element, save_path: Path) -> bool:
|
|
78
|
+
validation_errors = _validate_root_get_validation_messages(root)
|
|
79
|
+
if validation_errors:
|
|
80
|
+
_emit_validation_errors(validation_errors, save_path)
|
|
81
|
+
return False
|
|
82
|
+
return True
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
def _validate_root_get_validation_messages(data_xml: etree._Element) -> list[XSDValidationMessage] | None:
|
|
86
|
+
if errors := _validate_xml_tree_against_schema(data_xml):
|
|
87
|
+
return _reformat_validation_errors(errors.error_log)
|
|
88
|
+
return None
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
def _emit_validation_errors(validation_errors: list[XSDValidationMessage], save_path: Path) -> None:
|
|
92
|
+
header_msg = f"During the XSD Schema validation the following {len(validation_errors)} error(s) were found: "
|
|
93
|
+
print(BACKGROUND_BOLD_RED, header_msg, RESET_TO_DEFAULT)
|
|
94
|
+
logger.error(header_msg)
|
|
95
|
+
if len(validation_errors) > 50:
|
|
96
|
+
save_path = save_path / "xsd_validation_errors.csv"
|
|
97
|
+
message_dicts = [vars(x) for x in validation_errors]
|
|
98
|
+
df = pd.DataFrame.from_records(message_dicts)
|
|
99
|
+
df.to_csv(save_path, index=False)
|
|
100
|
+
msg = f"Due to the large number of errors they are saved in the file '{save_path}'."
|
|
101
|
+
print(BOLD_RED + msg, RESET_TO_DEFAULT)
|
|
102
|
+
logger.error(msg)
|
|
103
|
+
else:
|
|
104
|
+
for one_msg in validation_errors:
|
|
105
|
+
msg_str = get_xsd_validation_message_str(one_msg)
|
|
106
|
+
print(BOLD_RED, msg_str, RESET_TO_DEFAULT)
|
|
107
|
+
logger.error(msg_str)
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
def _reformat_validation_errors(log: etree._ListErrorLog) -> list[XSDValidationMessage]:
|
|
111
|
+
res = [_reformat_error_message_str(err.message, err.line) for err in log]
|
|
112
|
+
return [x for x in res if x]
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
def _reformat_error_message_str(msg: str, line_number: int) -> XSDValidationMessage | None:
|
|
116
|
+
element, attrib = None, None
|
|
117
|
+
msg = msg.replace("{https://dasch.swiss/schema}", "")
|
|
118
|
+
first, message = msg.split(":", maxsplit=1)
|
|
119
|
+
if ele_found := regex.search(r"Element '(.*?)'", first):
|
|
120
|
+
element = ele_found.group(1)
|
|
121
|
+
if attrib_found := regex.search(r"attribute '(.*?)'", first):
|
|
122
|
+
attrib = attrib_found.group(1)
|
|
123
|
+
if "No precomputed value available, the value was either invalid or something strange happened" in message:
|
|
124
|
+
return None
|
|
125
|
+
if " is not a valid value of the atomic type 'xs:ID'." in message:
|
|
126
|
+
if found := regex.search(r"'.*?'", message):
|
|
127
|
+
id_ = found.group(0)
|
|
128
|
+
else:
|
|
129
|
+
id_ = ""
|
|
130
|
+
message = (
|
|
131
|
+
f"The provided resource id {id_} is either not a valid xsd:ID or not unique in the file."
|
|
132
|
+
"The function make_xsd_compatible_id() assists you in creating IDs."
|
|
133
|
+
)
|
|
134
|
+
else:
|
|
135
|
+
message = regex.sub(r"\[facet .+\] ", "", message)
|
|
136
|
+
message = regex.sub(r"pattern ('.+')", "pattern for this value", message).strip()
|
|
137
|
+
return XSDValidationMessage(line_number=line_number, element=element, attribute=attrib, message=message)
|
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
# CLAUDE.md - xmllib Module
|
|
2
|
+
|
|
3
|
+
This file provides guidance to Claude Code when working with the `xmllib` module in dsp-tools.
|
|
4
|
+
|
|
5
|
+
## Module Overview
|
|
6
|
+
|
|
7
|
+
The `xmllib` module is the public API library for programmatic creation of DSP XML files.
|
|
8
|
+
It provides a type-safe, validated approach to generating XML data that conforms to DSP (DaSCH Service Platform) requirements.
|
|
9
|
+
|
|
10
|
+
## Architecture
|
|
11
|
+
|
|
12
|
+
### Core Components
|
|
13
|
+
|
|
14
|
+
#### Public API Layer (`__init__.py`)
|
|
15
|
+
|
|
16
|
+
- **Primary Interface**: All public functions and classes are exported here
|
|
17
|
+
- **Helper Functions**: Utilities for XML generation, validation, and formatting
|
|
18
|
+
- **Value Processing**: Checkers and converters for different data types
|
|
19
|
+
|
|
20
|
+
#### Models Layer (`models/`)
|
|
21
|
+
|
|
22
|
+
- **XMLRoot**: Main container for XML documents (`models/root.py`)
|
|
23
|
+
- **Resource**: Primary resource class for DSP resources (`models/res.py`)
|
|
24
|
+
- **DSP Base Resources**: Specialized resource types (`models/dsp_base_resources.py`)
|
|
25
|
+
- **Configuration**: Enums and options (`models/config_options.py`)
|
|
26
|
+
- **Licenses**: License definitions (`models/licenses/`)
|
|
27
|
+
- **Internal Models**: Value types and file models (`models/internal/`)
|
|
28
|
+
|
|
29
|
+
#### Utilities Layer
|
|
30
|
+
|
|
31
|
+
- **general_functions.py**: Public utility functions for XML creation
|
|
32
|
+
- **value_checkers.py**: Validation functions for data types
|
|
33
|
+
- **value_converters.py**: Data conversion utilities
|
|
34
|
+
|
|
35
|
+
#### Internal Layer (`internal/`)
|
|
36
|
+
|
|
37
|
+
- **checkers.py**: Type checking and input validation functions
|
|
38
|
+
- **input_converters.py**: Data conversion utilities for internal use
|
|
39
|
+
- **Serialization**: XML output generation (`serialise_resource.py`, `serialise_values.py`, `serialise_file_value.py`)
|
|
40
|
+
- **constants.py**: Constants used in several other files
|
|
41
|
+
- **type_aliases.py**: Type definitions and aliases
|
|
42
|
+
- **circumvent_circular_imports.py**: Place for functions that would produce a circular import error in other places
|
|
43
|
+
|
|
44
|
+
### Data Flow
|
|
45
|
+
|
|
46
|
+
```text
|
|
47
|
+
Raw Data → Validation → Resource Creation → XML Serialization
|
|
48
|
+
↓ ↓ ↓ ↓
|
|
49
|
+
Input Converters → Checkers → Models/Values → XML Output
|
|
50
|
+
(internal/) (internal/) (models/) (internal/)
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Key Classes and Usage Patterns
|
|
54
|
+
|
|
55
|
+
### XMLRoot - Document Container
|
|
56
|
+
|
|
57
|
+
```python
|
|
58
|
+
root = XMLRoot.create_new(shortcode="0000", default_ontology="onto")
|
|
59
|
+
root.add_resource(resource)
|
|
60
|
+
root.serialise_to_file("output.xml")
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### Resource - Core Data Model
|
|
64
|
+
|
|
65
|
+
```python
|
|
66
|
+
resource = Resource.create_new(
|
|
67
|
+
res_id="resource_1",
|
|
68
|
+
restype=":Person",
|
|
69
|
+
label="John Doe"
|
|
70
|
+
)
|
|
71
|
+
resource.add_simpletext(prop_name=":hasName", value="John Doe")
|
|
72
|
+
resource.add_date(prop_name=":hasBirthdate", value="GREGORIAN:CE:1990-01-01")
|
|
73
|
+
resource.add_integer(prop_name=":hasAge", value=33)
|
|
74
|
+
resource.add_link(prop_name=":hasPartner", value="resource_2")
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### Specialized Resources
|
|
78
|
+
|
|
79
|
+
```python
|
|
80
|
+
# Region of Interest
|
|
81
|
+
region = RegionResource.create_new(
|
|
82
|
+
res_id="region_1",
|
|
83
|
+
label="ROI 1",
|
|
84
|
+
region_of="image_1",
|
|
85
|
+
).add_rectangle(
|
|
86
|
+
(0.5, 0.2),
|
|
87
|
+
(0.1, 0.3),
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
# Video Segment
|
|
91
|
+
segment = VideoSegmentResource.create_new(
|
|
92
|
+
res_id="segment_1",
|
|
93
|
+
label="The second minute of the video",
|
|
94
|
+
segment_of="video_1",
|
|
95
|
+
segment_start="60",
|
|
96
|
+
segment_end="120"
|
|
97
|
+
)
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## Value Types and Validation
|
|
101
|
+
|
|
102
|
+
### Supported Value Types
|
|
103
|
+
|
|
104
|
+
- **SimpleText**: Plain text values
|
|
105
|
+
- **Richtext**: Formatted text with standoff markup
|
|
106
|
+
- **Integer**: Numeric integers
|
|
107
|
+
- **Decimal**: Floating point numbers
|
|
108
|
+
- **Boolean**: True/false values
|
|
109
|
+
- **Date**: Calendar dates with era and precision. Always as data range with start and end.
|
|
110
|
+
- **Time**: Timestamps
|
|
111
|
+
- **Color**: Hex color values
|
|
112
|
+
- **URI**: Web addresses and identifiers
|
|
113
|
+
- **Geoname**: Geographic location references, as geoname.org identifiers
|
|
114
|
+
- **List**: Controlled vocabulary values
|
|
115
|
+
- **Link**: References to other resources
|
|
116
|
+
- **File**: Multimedia file attachments
|
|
117
|
+
|
|
118
|
+
### Validation Functions
|
|
119
|
+
|
|
120
|
+
```python
|
|
121
|
+
# Check data types
|
|
122
|
+
date_value = reformat_date("1.1.1990", ".", None, DateFormat.DD_MM_YYYY)
|
|
123
|
+
assert is_date(date_value)
|
|
124
|
+
|
|
125
|
+
if is_bool_like("yes"):
|
|
126
|
+
bool_value = convert_to_bool_string("yes")
|
|
127
|
+
|
|
128
|
+
if is_color("#FF0000"):
|
|
129
|
+
# Valid hex color
|
|
130
|
+
pass
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
## Configuration Options
|
|
134
|
+
|
|
135
|
+
### Permissions
|
|
136
|
+
|
|
137
|
+
- `PROJECT_SPECIFIC_PERMISSIONS`: Use project defaults
|
|
138
|
+
- `OPEN`: Publicly accessible
|
|
139
|
+
- `RESTRICTED`: Only visible for project members
|
|
140
|
+
- `RESTRICTED_VIEW`: Only applicable for images: Publicly accessible,
|
|
141
|
+
but users who are not project members see the image in lower resolution or with a watermark
|
|
142
|
+
|
|
143
|
+
### Date Formatting
|
|
144
|
+
|
|
145
|
+
- `DateFormat.YYYY_MM_DD`: ISO format (2023-12-31)
|
|
146
|
+
- `DateFormat.DD_MM_YYYY`: European format (31.12.2023)
|
|
147
|
+
- `DateFormat.MM_DD_YYYY`: US format (12/31/2023)
|
|
148
|
+
|
|
149
|
+
### Calendar Systems
|
|
150
|
+
|
|
151
|
+
- `Calendar.GREGORIAN`: Modern standard calendar
|
|
152
|
+
- `Calendar.JULIAN`: Julian calender, only used for historical dates
|
|
153
|
+
- `Calendar.ISLAMIC`: Islamic calendar
|
|
154
|
+
|
|
155
|
+
### Text Processing
|
|
156
|
+
|
|
157
|
+
- `NewlineReplacement.PARAGRAPH`: Convert linebreaks to `<p>` tags
|
|
158
|
+
- `NewlineReplacement.LINEBREAK`: Convert linebreaks to `<br>` tags
|
|
159
|
+
- `NewlineReplacement.NONE`: Preserve linebreaks as-is
|
|
160
|
+
|
|
161
|
+
## Rich Text and Standoff Markup
|
|
162
|
+
|
|
163
|
+
### Creating Links
|
|
164
|
+
|
|
165
|
+
```python
|
|
166
|
+
# Link to another resource
|
|
167
|
+
link_text = create_standoff_link_to_resource("target_resource_id", "link text")
|
|
168
|
+
|
|
169
|
+
# Link to external URI
|
|
170
|
+
uri_link = create_standoff_link_to_uri("https://example.com", "external link")
|
|
171
|
+
|
|
172
|
+
# Add to richtext
|
|
173
|
+
resource.add_richtext(prop_name=":hasDescription", value=f"See {link_text} for details")
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
### Footnotes
|
|
177
|
+
|
|
178
|
+
```python
|
|
179
|
+
# Create footnote
|
|
180
|
+
footnote = create_footnote_string("This is a footnote")
|
|
181
|
+
footnote_element = create_footnote_element("Footnote text")
|
|
182
|
+
resource.add_richtext(prop_name=":hasDescription", value=f"Rich text with a footnote: {footnote}")
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
## Error Handling
|
|
186
|
+
|
|
187
|
+
### Warning System
|
|
188
|
+
|
|
189
|
+
- **Input Warnings**: Non-fatal data issues with input data
|
|
190
|
+
- **Type Mismatches**: Automatic conversion with notification
|
|
191
|
+
- **Validation Failures**: Clear error messages with resource context
|
|
192
|
+
|
|
193
|
+
### Error Types
|
|
194
|
+
|
|
195
|
+
```python
|
|
196
|
+
# Warning for non-fatal issues
|
|
197
|
+
emit_xmllib_input_warning("Non-standard boolean value converted")
|
|
198
|
+
|
|
199
|
+
# Type mismatch warning
|
|
200
|
+
if not is_color(val):
|
|
201
|
+
emit_xmllib_input_type_mismatch_warning(expected_type="color", value=val, res_id=resource_id, prop_name=prop_name)
|
|
202
|
+
|
|
203
|
+
# Input validation errors
|
|
204
|
+
raise_input_error(MessageInfo(f"Invalid date format: {date}", resource_id="res_1", prop_name=":hasDate"))
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
## Testing Approach
|
|
208
|
+
|
|
209
|
+
### Unit Tests (`test/unittests/xmllib`)
|
|
210
|
+
|
|
211
|
+
- Individual function validation
|
|
212
|
+
- Type checking verification
|
|
213
|
+
- Data conversion accuracy
|
|
214
|
+
|
|
215
|
+
### Integration Tests (`test/integration/xmllib`)
|
|
216
|
+
|
|
217
|
+
- Multi-resource XML generation
|
|
218
|
+
- Cross-module compatibility
|
|
219
|
+
- File I/O operations
|
|
220
|
+
|
|
221
|
+
## Common Patterns
|
|
222
|
+
|
|
223
|
+
### Resource Creation Pipeline
|
|
224
|
+
|
|
225
|
+
1. **Validate Input**: Use checker functions
|
|
226
|
+
2. **Convert Data**: Apply converters if needed
|
|
227
|
+
3. **Create Resource**: Instantiate with validated data
|
|
228
|
+
4. **Add Values**: Use typed `add_xyz()` methods
|
|
229
|
+
5. **Serialize**: Generate XML output
|
|
230
|
+
|
|
231
|
+
### Batch Processing
|
|
232
|
+
|
|
233
|
+
```python
|
|
234
|
+
# Process multiple resources
|
|
235
|
+
for data_row in dataset:
|
|
236
|
+
resource = Resource.create_new(
|
|
237
|
+
res_id=make_xsd_compatible_id(data_row['id']),
|
|
238
|
+
restype=data_row['type'],
|
|
239
|
+
label=clean_whitespaces_from_string(data_row['label'])
|
|
240
|
+
)
|
|
241
|
+
|
|
242
|
+
# Add values with validation
|
|
243
|
+
for prop, value in data_row.items():
|
|
244
|
+
if is_nonempty_value(value):
|
|
245
|
+
resource.add_simpletext(prop_name=prop, value=str(value))
|
|
246
|
+
|
|
247
|
+
root.add_resource(resource)
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
### List Value Processing
|
|
251
|
+
|
|
252
|
+
```python
|
|
253
|
+
# Work with controlled vocabularies
|
|
254
|
+
lookup = ListLookup(project_lists)
|
|
255
|
+
string_with_list_labels = "Label 1; Label 2"
|
|
256
|
+
nodes = get_list_nodes_from_string_via_list_name(
|
|
257
|
+
string_with_list_labels="Label 1; Label 2",
|
|
258
|
+
label_separator=";",
|
|
259
|
+
list_name="list1",
|
|
260
|
+
list_lookup=list_lookup,
|
|
261
|
+
)
|
|
262
|
+
assert nodes == ["node1", "node2"]
|
|
263
|
+
resource.add_list_multiple(prop_name=":hasColor", list_name="list1", values=list_nodes)
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
## Important Guidelines
|
|
267
|
+
|
|
268
|
+
### Type Safety
|
|
269
|
+
|
|
270
|
+
- Always use type hints in new code
|
|
271
|
+
- Leverage dataclass models for structured data
|
|
272
|
+
- Use validation functions before creating values
|
|
273
|
+
|
|
274
|
+
### Maintainability
|
|
275
|
+
|
|
276
|
+
- Follow existing patterns for new value types
|
|
277
|
+
- Add comprehensive docstrings for public functions
|
|
278
|
+
- Include validation logic with clear error messages
|
|
279
|
+
|
|
280
|
+
## Dependencies
|
|
281
|
+
|
|
282
|
+
### External
|
|
283
|
+
|
|
284
|
+
- `lxml`: XML processing and validation
|
|
285
|
+
- `pandas`: Data manipulation (NA handling)
|
|
286
|
+
- `regex`: Unicode-aware pattern matching
|
|
287
|
+
- `loguru`: Structured logging
|
|
288
|
+
|
|
289
|
+
### Internal
|
|
290
|
+
|
|
291
|
+
- `dsp_tools.error`: Warning and error system
|
|
292
|
+
- `dsp_tools.utils`: Data format utilities
|
|
293
|
+
- Type definitions and constants
|
|
294
|
+
|
|
295
|
+
## Migration Notes
|
|
296
|
+
|
|
297
|
+
When updating xmllib:
|
|
298
|
+
|
|
299
|
+
- Maintain backward compatibility in public API
|
|
300
|
+
- Add deprecation warnings before removing features
|
|
301
|
+
- Update type hints for new Python versions
|
|
302
|
+
- Ensure XML schema compliance is preserved
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
from dsp_tools.error.xmllib_warnings_util import initialise_warning_file
|
|
2
|
+
|
|
3
|
+
from .general_functions import ListLookup as ListLookup
|
|
4
|
+
from .general_functions import clean_whitespaces_from_string as clean_whitespaces_from_string
|
|
5
|
+
from .general_functions import create_footnote_element as create_footnote_element
|
|
6
|
+
from .general_functions import create_footnote_string as create_footnote_string
|
|
7
|
+
from .general_functions import create_list_from_input as create_list_from_input
|
|
8
|
+
from .general_functions import create_list_from_string as create_list_from_string
|
|
9
|
+
from .general_functions import create_non_empty_list_from_string as create_non_empty_list_from_string
|
|
10
|
+
from .general_functions import create_standoff_link_to_resource as create_standoff_link_to_resource
|
|
11
|
+
from .general_functions import create_standoff_link_to_uri as create_standoff_link_to_uri
|
|
12
|
+
from .general_functions import escape_reserved_xml_characters as escape_reserved_xml_characters
|
|
13
|
+
from .general_functions import find_license_in_string as find_license_in_string
|
|
14
|
+
from .general_functions import get_list_nodes_from_string_via_list_name as get_list_nodes_from_string_via_list_name
|
|
15
|
+
from .general_functions import get_list_nodes_from_string_via_property as get_list_nodes_from_string_via_property
|
|
16
|
+
from .general_functions import make_xsd_compatible_id as make_xsd_compatible_id
|
|
17
|
+
from .general_functions import make_xsd_compatible_id_with_uuid as make_xsd_compatible_id_with_uuid
|
|
18
|
+
from .models.config_options import NewlineReplacement as NewlineReplacement
|
|
19
|
+
from .models.date_formats import Calendar as Calendar
|
|
20
|
+
from .models.date_formats import DateFormat as DateFormat
|
|
21
|
+
from .models.date_formats import Era as Era
|
|
22
|
+
from .models.dsp_base_resources import AudioSegmentResource as AudioSegmentResource
|
|
23
|
+
from .models.dsp_base_resources import LinkResource as LinkResource
|
|
24
|
+
from .models.dsp_base_resources import RegionResource as RegionResource
|
|
25
|
+
from .models.dsp_base_resources import VideoSegmentResource as VideoSegmentResource
|
|
26
|
+
from .models.licenses.other import LicenseOther as LicenseOther
|
|
27
|
+
from .models.licenses.recommended import LicenseRecommended as LicenseRecommended
|
|
28
|
+
from .models.permissions import Permissions as Permissions
|
|
29
|
+
from .models.res import Resource as Resource
|
|
30
|
+
from .models.root import XMLRoot as XMLRoot
|
|
31
|
+
from .value_checkers import check_richtext_syntax as check_richtext_syntax
|
|
32
|
+
from .value_checkers import is_bool_like as is_bool_like
|
|
33
|
+
from .value_checkers import is_color as is_color
|
|
34
|
+
from .value_checkers import is_date as is_date
|
|
35
|
+
from .value_checkers import is_decimal as is_decimal
|
|
36
|
+
from .value_checkers import is_dsp_ark as is_dsp_ark
|
|
37
|
+
from .value_checkers import is_dsp_iri as is_dsp_iri
|
|
38
|
+
from .value_checkers import is_geoname as is_geoname
|
|
39
|
+
from .value_checkers import is_integer as is_integer
|
|
40
|
+
from .value_checkers import is_nonempty_value as is_nonempty_value
|
|
41
|
+
from .value_checkers import is_timestamp as is_timestamp
|
|
42
|
+
from .value_converters import convert_to_bool_string as convert_to_bool_string
|
|
43
|
+
from .value_converters import find_dates_in_string as find_dates_in_string
|
|
44
|
+
from .value_converters import reformat_date as reformat_date
|
|
45
|
+
from .value_converters import replace_newlines_with_br_tags as replace_newlines_with_br_tags
|
|
46
|
+
from .value_converters import replace_newlines_with_paragraph_tags as replace_newlines_with_paragraph_tags
|
|
47
|
+
from .value_converters import replace_newlines_with_tags as replace_newlines_with_tags
|
|
48
|
+
|
|
49
|
+
initialise_warning_file()
|