diff --git a/astropy/io/votable/data/VOTable.v1.5.xsd b/astropy/io/votable/data/VOTable.v1.5.xsd
new file mode 100644
index 000000000000..84a7cba03712
--- /dev/null
+++ b/astropy/io/votable/data/VOTable.v1.5.xsd
@@ -0,0 +1,634 @@
+
+
+
+
+ VOTable is meant to serialize tabular documents in the
+ context of Virtual Observatory applications. This schema
+ corresponds to the VOTable document available from
+ http://www.ivoa.net/Documents/latest/VOT.html
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Accept UCD1+
+ Accept also old UCD1 (but not / + %) including SIAP convention (with :)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ content-role was previsouly restricted as:
+
+
+
+
+
+
+
+
+ ]]>; is now a token.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Values for this attribute must be taken from the IVOA
+ refframe vocabulary, http://www.ivoa.net/rdf/refframe
+
+
+
+
+
+
+ The reference position SHOULD be taken from the IVOA
+ refposition vocabulary (http://www.ivoa.net/rdf/refposition).
+
+
+
+
+
+
+
+
+
+
+ This is a time origin of a time coordinate, given as a
+ Julian Date for the the time scale and reference point
+ defined. It is usually given as a floating point
+ literal; for convenience, the magic strings “MJD-origin”
+ (standing for 2400000.5) and “JD-origin” (standing for 0)
+ are also allowed.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ The time origin is the offset or the time coordinate to Julian
+ Date. The timeorigin attribute MUST be given unless the time's
+ representation contains a year of a calendar era, in which case it
+ MUST NOT be present.
+
+
+
+
+
+
+ This is the time scale used. Values SHOULD be
+ taken from the IVOA timescale vocabulary (http://www.ivoa.net/rdf/timescale).
+
+
+
+
+
+
+ The reference position SHOULD be taken from the IVOA
+ refposition vocabulary (http://www.ivoa.net/rdf/refposition).
+
+
+
+
+
+
+
+
+
+ Deprecated in Version 1.1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Added in Version 1.2: INFO for diagnostics
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ The 'encoding' attribute is added here to avoid
+ problems of code generators which do not properly
+ interpret the TR/TD structures.
+ 'encoding' was chosen because it appears in
+ appendix A.5
+
+
+
+
+
+
+
+
+ The ID attribute is added here to the TR tag to avoid
+ problems of code generators which do not properly
+ interpret the TR/TD structures
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Added in Version 1.2: INFO for diagnostics
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Added in Version 1.2: INFO for diagnostics in several places
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/astropy/io/votable/exceptions.py b/astropy/io/votable/exceptions.py
index 1050c330c735..629f6672904e 100644
--- a/astropy/io/votable/exceptions.py
+++ b/astropy/io/votable/exceptions.py
@@ -660,12 +660,12 @@ class W20(VOTableSpecWarning):
class W21(UnimplementedWarning):
"""
Unknown issues may arise using ``astropy.io.votable`` with VOTable files
- from a version other than 1.1, 1.2, 1.3, or 1.4.
+ from a version not in 1.1 through 1.5.
"""
message_template = (
- "astropy.io.votable is designed for VOTable version 1.1, 1.2, 1.3,"
- " and 1.4, but this file is {}"
+ "astropy.io.votable is designed for VOTable versions 1.1 through 1.5,"
+ " but this file is {}"
)
default_args = ("x",)
@@ -1156,6 +1156,20 @@ class W56(VOTableSpecWarning):
)
+class W57(VOTableSpecWarning):
+ """
+ The ``refposition`` attribute on the ``COOSYS`` element is only allowed on
+ VOTABLE versions 1.5 and greater.
+ favor of a reference to the Space-Time Coordinate (STC) data
+ model (see `utype
+ `__
+ and the IVOA note `referencing STC in VOTable
+ `__.
+ """
+
+ message_template = "refposition only allowed on VOTABLE v1.5 and greater"
+
+
class E01(VOWarning, ValueError):
"""Invalid size specifier for a field.
diff --git a/astropy/io/votable/tests/data/coosys.xml b/astropy/io/votable/tests/data/coosys.xml
new file mode 100644
index 000000000000..eaab39880c89
--- /dev/null
+++ b/astropy/io/votable/tests/data/coosys.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 010.68 |
+ +41.27 |
+ N 224 |
+
+
+
+
+
+
diff --git a/astropy/io/votable/tests/test_coosys.py b/astropy/io/votable/tests/test_coosys.py
new file mode 100644
index 000000000000..9eaed9cd99c8
--- /dev/null
+++ b/astropy/io/votable/tests/test_coosys.py
@@ -0,0 +1,212 @@
+# Licensed under a 3-clause BSD style license - see LICENSE.rst
+import io
+from contextlib import nullcontext
+
+import pytest
+
+from astropy.io.votable import tree
+from astropy.io.votable.exceptions import W07, W08, W21, W27, W41, W57
+from astropy.io.votable.table import parse
+from astropy.io.votable.tree import Resource, VOTableFile
+from astropy.tests.helper import PYTEST_LT_8_0
+from astropy.utils.data import get_pkg_data_filename
+
+COOSYS_TEMPLATE = """
+
+
+ {}
+
+
+"""
+
+COOSYS_REFPOSITION = (
+ ''
+)
+COOSYS_NO_REFPOSITION = ''
+NO_COOSYS = ""
+
+
+def test_accept_refposition():
+ for ns_version, version, coosys, err in [
+ ("1.1", "1.1", COOSYS_NO_REFPOSITION, None),
+ ("1.2", "1.2", COOSYS_NO_REFPOSITION, (W27)),
+ ("1.3", "1.3", COOSYS_NO_REFPOSITION, None),
+ ("1.3", "1.4", COOSYS_NO_REFPOSITION, None),
+ ("1.3", "1.5", COOSYS_NO_REFPOSITION, None),
+ ("1.1", "1.1", COOSYS_REFPOSITION, (W57)),
+ ("1.2", "1.2", COOSYS_REFPOSITION, (W27, W57)),
+ ("1.3", "1.3", COOSYS_REFPOSITION, (W57)),
+ ("1.3", "1.4", COOSYS_REFPOSITION, (W57)),
+ ("1.3", "1.5", COOSYS_REFPOSITION, None),
+ ]:
+ xml_string = COOSYS_TEMPLATE.format(ns_version, version, coosys)
+ input = io.BytesIO(bytes(xml_string, "utf-8"))
+ if err is not None:
+ with pytest.warns() as record:
+ vot = parse(input, verify="warn")
+ else:
+ vot = parse(input, verify="warn")
+
+
+def _coosys_tests(votable):
+ assert len(list(votable.iter_coosys())) == 2
+
+ coosys = votable.get_coosys_by_id("coosys1")
+ assert coosys.system == "ICRS"
+ assert coosys.equinox == "J2000"
+ assert coosys.epoch == "J2015.5"
+ assert coosys.refposition == "BARYCENTER"
+
+ coosys = votable.get_coosys_by_id("coosys2")
+ assert coosys.system == "FK4"
+ assert coosys.equinox == "B1950"
+ assert coosys.epoch == "B1950.0"
+ assert coosys.refposition == "UNKNOWN"
+
+
+def test_coosys():
+ votable = parse(get_pkg_data_filename("data/coosys.xml"))
+ _coosys_tests(votable)
+
+
+def test_coosys_roundtrip():
+ orig_votable = parse(get_pkg_data_filename("data/coosys.xml"))
+ bio = io.BytesIO()
+ orig_votable.to_xml(bio)
+ bio.seek(0)
+ votable = parse(bio)
+ _coosys_tests(votable)
+
+
+if __name__ == "__main__":
+ test_accept_refposition()
+
+
+def test_check_astroyear_fail():
+ config = {"verify": "exception"}
+ field = tree.Field(None, name="astroyear", arraysize="1")
+ with pytest.raises(W07):
+ tree.check_astroyear("X2100", field, config)
+
+
+def test_string_fail():
+ config = {"verify": "exception"}
+ with pytest.raises(W08):
+ tree.check_string(42, "foo", config)
+
+
+def test_make_Fields():
+ votable = VOTableFile()
+ # ...with one resource...
+ resource = Resource()
+ votable.resources.append(resource)
+
+ # ... with one table
+ table = tree.TableElement(votable)
+ resource.tables.append(table)
+
+ table.fields.extend(
+ [tree.Field(votable, name="Test", datatype="float", unit="mag")]
+ )
+
+
+def test_unit_format():
+ data = parse(get_pkg_data_filename("data/irsa-nph-error.xml"))
+ assert data._config["version"] == "1.0"
+ assert tree._get_default_unit_format(data._config) == "cds"
+ data = parse(get_pkg_data_filename("data/names.xml"))
+ assert data._config["version"] == "1.1"
+ assert tree._get_default_unit_format(data._config) == "cds"
+ data = parse(get_pkg_data_filename("data/gemini.xml"))
+ assert data._config["version"] == "1.2"
+ assert tree._get_default_unit_format(data._config) == "cds"
+ data = parse(get_pkg_data_filename("data/binary2_masked_strings.xml"))
+ assert data._config["version"] == "1.3"
+ assert tree._get_default_unit_format(data._config) == "cds"
+ data = parse(get_pkg_data_filename("data/timesys.xml"))
+ assert data._config["version"] == "1.4"
+ assert tree._get_default_unit_format(data._config) == "vounit"
+
+
+def test_namespace_warning():
+ """
+ A version 1.4 VOTable must use the same namespace as 1.3.
+ (see https://www.ivoa.net/documents/VOTable/20191021/REC-VOTable-1.4-20191021.html#ToC16).
+ """
+ bad_namespace = b"""
+
+
+
+ """
+ with pytest.warns(W41):
+ parse(io.BytesIO(bad_namespace), verify="exception")
+
+ good_namespace_14 = b"""
+
+
+
+ """
+ parse(io.BytesIO(good_namespace_14), verify="exception")
+
+ good_namespace_13 = b"""
+
+
+
+ """
+ parse(io.BytesIO(good_namespace_13), verify="exception")
+
+
+def test_version():
+ """
+ VOTableFile.__init__ allows versions of '1.1' through '1.5'.
+ VOTableFile.__init__ does not allow version of '1.0' anymore and now raises a ValueError as it does to other versions not supported.
+ """
+ # Exercise the checks in __init__
+ for version in ("1.1", "1.2", "1.3", "1.4", "1.5"):
+ VOTableFile(version=version)
+ for version in ("0.9", "1.0", "1.6", "2.0"):
+ with pytest.raises(
+ ValueError, match=r"should be in \('1.1', '1.2', '1.3', '1.4', '1.5'\)."
+ ):
+ VOTableFile(version=version)
+
+ # Exercise the checks in the setter
+ vot = VOTableFile()
+ for version in ("1.1", "1.2", "1.3", "1.4"):
+ vot.version = version
+ for version in ("1.0", "1.6", "2.0"):
+ with pytest.raises(
+ ValueError,
+ match=r"supports VOTable versions '1.1', '1.2', '1.3', '1.4', '1.5'$",
+ ):
+ vot.version = version
+
+ # Exercise the checks in the parser.
+ begin = b''
+ )
+
+ # Valid versions
+ for bversion in (b"1.1", b"1.2", b"1.3"):
+ parse(
+ io.BytesIO(begin + bversion + middle + bversion + end), verify="exception"
+ )
+ parse(io.BytesIO(begin + b"1.4" + middle + b"1.3" + end), verify="exception")
+
+ if PYTEST_LT_8_0:
+ ctx = nullcontext()
+ else:
+ ctx = pytest.warns(W41)
+
+ # Invalid versions
+ for bversion in (b"1.0", b"2.0"):
+ with pytest.warns(W21), ctx:
+ parse(
+ io.BytesIO(begin + bversion + middle + bversion + end),
+ verify="exception",
+ )
diff --git a/astropy/io/votable/tests/test_schema_versions.py b/astropy/io/votable/tests/test_schema_versions.py
new file mode 100644
index 000000000000..cd986ad2f763
--- /dev/null
+++ b/astropy/io/votable/tests/test_schema_versions.py
@@ -0,0 +1,82 @@
+import re
+import sys
+
+import pytest
+
+from astropy.io.votable.xmlutil import validate_schema
+from astropy.utils.data import get_pkg_data_filename
+
+# Each test file uses a feature that is new with its version.
+V_1_2_TABLE = get_pkg_data_filename("data/empty_table.xml")
+V_1_3_TABLE = get_pkg_data_filename("data/binary2_masked_strings.xml")
+V_1_4_TABLE = get_pkg_data_filename("data/timesys.xml")
+V_1_5_TABLE = get_pkg_data_filename("data/coosys.xml")
+
+# Schema versions to test against
+V_1_2 = "1.2"
+V_1_3 = "1.3"
+V_1_4 = "1.4"
+V_1_5 = "1.5"
+V_1_6 = "1.6" # Next (unimplemented) schema
+
+# Starting with version 1.4, schemas were upward compatible.
+test_cases = [
+ (V_1_2_TABLE, V_1_2, 0, None),
+ (
+ V_1_2_TABLE,
+ V_1_3,
+ 3,
+ b"No matching global declaration available for the validation root",
+ ),
+ (V_1_3_TABLE, V_1_3, 0, None),
+ (V_1_3_TABLE, V_1_4, 0, None),
+ (V_1_3_TABLE, V_1_5, 0, None),
+ (
+ V_1_3_TABLE,
+ V_1_6,
+ 3,
+ b"No matching global declaration available for the validation root",
+ ),
+ (V_1_4_TABLE, V_1_3, 3, b"TIMESYS.*element is not expected"),
+ (V_1_4_TABLE, V_1_4, 0, None),
+ (V_1_4_TABLE, V_1_5, 0, None),
+ (
+ V_1_4_TABLE,
+ V_1_6,
+ 3,
+ b"No matching global declaration available for the validation root",
+ ),
+ (V_1_5_TABLE, V_1_3, 3, b"attribute 'refposition' is not allowed"),
+ (V_1_5_TABLE, V_1_4, 3, b"attribute 'refposition' is not allowed"),
+ (V_1_5_TABLE, V_1_5, 0, None),
+ (
+ V_1_5_TABLE,
+ V_1_6,
+ 3,
+ b"No matching global declaration available for the validation root",
+ ),
+]
+
+
+@pytest.mark.parametrize(
+ "votable_file,schema_version,expected_return_code,expected_msg_re", test_cases
+)
+def test_schema_versions(
+ votable_file, schema_version, expected_return_code, expected_msg_re
+):
+ """Test that xmllint gives expected results for the given file and schema version."""
+
+ # We need xmllint so won't try with Windows.
+ if sys.platform.startswith("win"):
+ return
+
+ try:
+ rc, stdout, stderr = validate_schema(votable_file, schema_version)
+ except OSError:
+ # If xmllint is not installed, we want the test to pass anyway
+ return
+
+ assert rc == expected_return_code
+ if rc == 3:
+ # Schema validation error. Check the error message content.
+ assert re.search(expected_msg_re, stderr)
diff --git a/astropy/io/votable/tests/test_tree.py b/astropy/io/votable/tests/test_tree.py
index 224d189a33f0..3625b216494a 100644
--- a/astropy/io/votable/tests/test_tree.py
+++ b/astropy/io/votable/tests/test_tree.py
@@ -117,25 +117,26 @@ def test_votable_values_empty_min_max():
def test_version():
"""
- VOTableFile.__init__ allows versions of '1.1', '1.2', '1.3' and '1.4'.
+ VOTableFile.__init__ allows versions of '1.1' through '1.5'.
VOTableFile.__init__ does not allow version of '1.0' anymore and now raises a ValueError as it does to other versions not supported.
"""
# Exercise the checks in __init__
- for version in ("1.1", "1.2", "1.3", "1.4"):
+ for version in ("1.1", "1.2", "1.3", "1.4", "1.5"):
VOTableFile(version=version)
- for version in ("0.9", "1.0", "2.0"):
+ for version in ("0.9", "1.0", "1.6", "2.0"):
with pytest.raises(
- ValueError, match=r"should be in \('1.1', '1.2', '1.3', '1.4'\)."
+ ValueError, match=r"should be in \('1.1', '1.2', '1.3', '1.4', '1.5'\)."
):
VOTableFile(version=version)
# Exercise the checks in the setter
vot = VOTableFile()
- for version in ("1.1", "1.2", "1.3", "1.4"):
+ for version in ("1.1", "1.2", "1.3", "1.4", "1.5"):
vot.version = version
- for version in ("1.0", "2.0"):
+ for version in ("1.0", "1.6", "2.0"):
with pytest.raises(
- ValueError, match=r"supports VOTable versions '1.1', '1.2', '1.3', '1.4'$"
+ ValueError,
+ match=r"supports VOTable versions '1.1', '1.2', '1.3', '1.4', '1.5'$",
):
vot.version = version
@@ -152,6 +153,7 @@ def test_version():
io.BytesIO(begin + bversion + middle + bversion + end), verify="exception"
)
parse(io.BytesIO(begin + b"1.4" + middle + b"1.3" + end), verify="exception")
+ parse(io.BytesIO(begin + b"1.5" + middle + b"1.3" + end), verify="exception")
if PYTEST_LT_8_0:
ctx = nullcontext()
@@ -198,6 +200,11 @@ def test_votable_tag():
assert 'xsi:schemaLocation="http://www.ivoa.net/xml/VOTable/v1.3 ' in xml
assert 'http://www.ivoa.net/xml/VOTable/VOTable-1.4.xsd"' in xml
+ xml = votable_xml_string("1.5")
+ assert 'xmlns="http://www.ivoa.net/xml/VOTable/v1.3"' in xml
+ assert 'xsi:schemaLocation="http://www.ivoa.net/xml/VOTable/v1.3 ' in xml
+ assert 'http://www.ivoa.net/xml/VOTable/VOTable-1.5.xsd"' in xml
+
def _squash_xml(data):
"""
diff --git a/astropy/io/votable/tree.py b/astropy/io/votable/tree.py
index 2a040c19888c..303a8d97e21c 100644
--- a/astropy/io/votable/tree.py
+++ b/astropy/io/votable/tree.py
@@ -79,6 +79,7 @@
W53,
W54,
W56,
+ W57,
vo_raise,
vo_reraise,
vo_warn,
@@ -1810,7 +1811,7 @@ class CooSys(SimpleElement):
name, documented below.
"""
- _attr_list = ["ID", "equinox", "epoch", "system"]
+ _attr_list = ["ID", "equinox", "epoch", "system", "refposition"]
_element_name = "COOSYS"
def __init__(
@@ -1819,6 +1820,7 @@ def __init__(
equinox=None,
epoch=None,
system=None,
+ refposition=None,
id=None,
config=None,
pos=None,
@@ -1841,6 +1843,11 @@ def __init__(
self.equinox = equinox
self.epoch = epoch
self.system = system
+ self.refposition = refposition
+
+ # refposition introduced in v1.5.
+ if self.refposition is not None and not config.get("version_1_5_or_later"):
+ warn_or_raise(W57, W57, (), config, pos)
warn_unknown_attrs("COOSYS", extra.keys(), config, pos)
@@ -1886,7 +1893,10 @@ def system(self, system):
"barycentric",
"geo_app",
):
- warn_or_raise(E16, E16, system, self._config, self._pos)
+ if not self._config.get("version_1_5_or_later"):
+ # Starting in v1.5, system values come from the IVOA refframe vocabulary
+ # (http://www.ivoa.net/rdf/refframe). For now we are not checking those values.
+ warn_or_raise(E16, E16, system, self._config, self._pos)
self._system = system
@system.deleter
@@ -4143,6 +4153,7 @@ def _get_version_checks(self):
config["version_1_2_or_later"] = util.version_compare(self.version, "1.2") >= 0
config["version_1_3_or_later"] = util.version_compare(self.version, "1.3") >= 0
config["version_1_4_or_later"] = util.version_compare(self.version, "1.4") >= 0
+ config["version_1_5_or_later"] = util.version_compare(self.version, "1.5") >= 0
return config
# Map VOTable version numbers to namespace URIs and schema information.
@@ -4186,6 +4197,14 @@ def _get_version_checks(self):
" http://www.ivoa.net/xml/VOTable/VOTable-1.4.xsd"
),
},
+ "1.5": {
+ "namespace_uri": "http://www.ivoa.net/xml/VOTable/v1.3",
+ "schema_location_attr": "xsi:schemaLocation",
+ "schema_location_value": (
+ "http://www.ivoa.net/xml/VOTable/v1.3"
+ " http://www.ivoa.net/xml/VOTable/VOTable-1.5.xsd"
+ ),
+ },
}
def parse(self, iterator, config):
diff --git a/astropy/io/votable/validator/result.py b/astropy/io/votable/validator/result.py
index cb9d6fcc1fc2..b047a80ef73a 100644
--- a/astropy/io/votable/validator/result.py
+++ b/astropy/io/votable/validator/result.py
@@ -243,6 +243,9 @@ def get_result_subsets(results, root, s=None):
version_10 = []
version_11 = []
version_12 = []
+ version_13 = []
+ version_14 = []
+ version_15 = []
version_unknown = []
has_warnings = []
warning_set = {}
@@ -286,6 +289,12 @@ def get_result_subsets(results, root, s=None):
version_11.append(x)
elif version == "1.2":
version_12.append(x)
+ elif version == "1.3":
+ version_13.append(x)
+ elif version == "1.4":
+ version_14.append(x)
+ elif version == "1.5":
+ version_15.append(x)
else:
version_unknown.append(x)
if x["nwarnings"] > 0:
@@ -332,6 +341,9 @@ def get_result_subsets(results, root, s=None):
("version1.0", "Version 1.0", version_10),
("version1.1", "Version 1.1", version_11),
("version1.2", "Version 1.2", version_12),
+ ("version1.3", "Version 1.3", version_13),
+ ("version1.4", "Version 1.4", version_14),
+ ("version1.5", "Version 1.5", version_15),
("version_unknown", "Version unknown", version_unknown),
("warnings", "Warnings", has_warnings),
]
diff --git a/astropy/io/votable/xmlutil.py b/astropy/io/votable/xmlutil.py
index 2b98fe5767bd..c27c1611d38e 100644
--- a/astropy/io/votable/xmlutil.py
+++ b/astropy/io/votable/xmlutil.py
@@ -112,13 +112,14 @@ def validate_schema(filename, version="1.1"):
Returns the returncode from xmllint and the stdout and stderr
as strings
"""
- if version not in ("1.0", "1.1", "1.2", "1.3"):
- log.info(f"{filename} has version {version}, using schema 1.1")
- version = "1.1"
+ supported_schemas = ["1.1", "1.2", "1.3", "1.4", "1.5"]
- if version in ("1.1", "1.2", "1.3"):
- schema_path = data.get_pkg_data_filename(f"data/VOTable.v{version}.xsd")
- else:
+ if version == "1.0":
schema_path = data.get_pkg_data_filename("data/VOTable.dtd")
+ else:
+ if version not in supported_schemas:
+ log.info(f"{filename} has version {version}, using schema 1.1")
+ version = "1.1"
+ schema_path = data.get_pkg_data_filename(f"data/VOTable.v{version}.xsd")
return validate.validate_schema(filename, schema_path)