4040"""
4141
4242
43- # pylint: disable=C0103:invalid-name # On account of the module name, that is not snake-cased (required by Robot Framework).
44- # pylint: disable=C0302:too-many-lines # On account of the extensive docstrings and annotations.
45- # pylint: disable=C0301:line-too-long # On account of tables in docstrings.
43+ # pylint: disable=C0103:invalid-name # On account of the module name, that is not snake-cased (required by Robot Framework).
44+ # pylint: disable=C0302:too-many-lines # On account of the extensive docstrings and annotations.
45+ # pylint: disable=C0301:line-too-long # On account of tables in docstrings.
4646
4747
4848# Standard library imports.
@@ -82,19 +82,19 @@ class XmlValidator:
8282 The other keywords are convenience/helper functions, e.g. ``Reset
8383 Error Facets``.
8484
85- The ``Validate Xml Files`` validates one or more XML files against one
86- or more XSD schema files and collects and reports all encountered
87- errors.
85+ The ``Validate Xml Files`` validates one or more XML files against
86+ one or more XSD schema files and collects and reports all
87+ encountered errors.
8888
8989 The type of error that the keyword can detect is not limited to XSD
9090 violations, but may also pertain to malformed XML files (e.g. parse
9191 errors), empty files, unmatched XML files (no XSD match found) and
9292 others.
9393
9494 Errors that result from malformed XML files or from XSD violations
95- support detailed error reporting. Using the ``error_facets`` argument
96- you may specify the details the keyword should collect and report
97- about captured errors.
95+ support detailed error reporting. Using the ``error_facets``
96+ argument you may specify the details the keyword should collect and
97+ report about captured errors.
9898
9999 When operating in batch mode, the ``Validate Xml Files`` keyword
100100 always validates the entire set of passed XML files. That is, when
@@ -407,11 +407,11 @@ class XmlValidator:
407407 nr_instances = 0
408408
409409 def __init__ (
410- self ,
411- xsd_path : Optional [str | Path ] = None ,
412- base_url : Optional [str ] = None ,
413- error_facets : Optional [ List [str ] ] = None
414- ) -> None :
410+ self ,
411+ xsd_path : Optional [str | Path ] = None ,
412+ base_url : Optional [str ] = None ,
413+ error_facets : Optional [List [str ]] = None
414+ ) -> None :
415415 """
416416 **Library Scope**
417417
@@ -549,41 +549,10 @@ def __init__(
549549 self .validator_utils = ValidatorUtils ()
550550 self .validator_results = ValidatorResultRecorder ()
551551 # Initialize the xsd schema from the xsd_path, if provided.
552- if xsd_path :
553- # Try to get a single xsd file from the provided xsd_path.
554- xsd_file_path , is_single_xsd_file = (
555- self .validator_utils .get_file_paths (
556- xsd_path , 'xsd'
557- )
558- )
559- # We need (a path to) a single xsd file.
560- if not is_single_xsd_file :
561- raise ValueError (f"Got multiple xsd files: { xsd_file_path } ." )
562- # Handle incorrect file extension.
563- if xsd_file_path [0 ].suffix != '.xsd' :
564- # Raise a load error.
565- raise SystemError (
566- f"ValueError: { xsd_file_path [0 ]} is not an XSD file."
567- )
568- # Try to load the provided XSD file.
569- result = self ._load_schema (xsd_file_path [0 ], base_url )
570- if result .success :
571- # Set the loaded XSD file as default schema.
572- self .schema = result .value
573- logger .info (
574- f"Schema '{ self .schema .name } ' set." , # type: ignore
575- also_console = True )
576- else :
577- # Or report the load error.
578- raise SystemError (f"Loading of schema failed: { result .error } " )
579- # Or inform the user on what to do.
580- else :
581- logger .info (
582- "No XSD schema set: provide schema(s) during keyword calls." ,
583- also_console = True
584- )
585- # And flag the schema attr as None.
586- self .schema = None
552+ self .schema = self ._try_load_initial_schema (
553+ xsd_path = xsd_path ,
554+ base_url = base_url
555+ )
587556 # Set the error facets to collect for failed XML validations.
588557 self .error_facets = error_facets if error_facets else [
589558 'path' , 'reason'
@@ -597,14 +566,14 @@ def __init__(
597566 logger .info (f'Number of library instances: { self .nr_instances } .' )
598567
599568 def _determine_validations (
600- self ,
601- xml_paths : List [Path ],
602- xsd_path : Optional [str | Path ] = None ,
603- xsd_search_strategy : Optional [
569+ self ,
570+ xml_paths : List [Path ],
571+ xsd_path : Optional [str | Path ] = None ,
572+ xsd_search_strategy : Optional [
604573 Literal ['by_namespace' , 'by_file_name' ]
605574 ] = None ,
606- base_url : Optional [str ] = None
607- ) -> Dict [Path , Path | None ]:
575+ base_url : Optional [str ] = None
576+ ) -> Dict [Path , Path | None ]:
608577 """
609578 Constructs a mapping between XML files and the XSD schemas to
610579 use for their validation.
@@ -744,10 +713,10 @@ class instance (i.e. during library initialization).
744713 return validations
745714
746715 def _ensure_schema (
747- self ,
748- xsd_path : Optional [Path ] = None ,
749- base_url : Optional [str ] = None
750- ) -> ValidatorResult :
716+ self ,
717+ xsd_path : Optional [Path ] = None ,
718+ base_url : Optional [str ] = None
719+ ) -> ValidatorResult :
751720 """
752721 Ensures that a schema is available for validation.
753722
@@ -829,15 +798,12 @@ def _ensure_schema(
829798 return self ._load_schema (xsd_path , base_url ) # pyright: ignore
830799
831800 def _find_schemas (
832- self ,
833- xml_file_paths : List [Path ],
834- xsd_file_paths : List [Path ],
835- search_by : Literal [
836- 'by_namespace' ,
837- 'by_file_name'
838- ] = 'by_namespace' ,
839- base_url : Optional [str ] = None
840- ) -> Dict [ Path , Path | None ]:
801+ self ,
802+ xml_file_paths : List [Path ],
803+ xsd_file_paths : List [Path ],
804+ search_by : Literal ['by_namespace' , 'by_file_name' ] = 'by_namespace' ,
805+ base_url : Optional [str ] = None
806+ ) -> Dict [ Path , Path | None ]:
841807 """
842808 Finds matching XSD schemas for XML files using the specified
843809 search strategy.
@@ -982,10 +948,10 @@ def _find_schemas(
982948 return validations
983949
984950 def _load_schema (
985- self ,
986- xsd_path : Path ,
987- base_url : Optional [str ] = None
988- ) -> ValidatorResult :
951+ self ,
952+ xsd_path : Path ,
953+ base_url : Optional [str ] = None
954+ ) -> ValidatorResult :
989955 """
990956 This method is responsible for initializing a schema object,
991957 using the `xmlschema` library.
@@ -1036,17 +1002,96 @@ def _load_schema(
10361002 success = False , error = {"XMLSchemaValidationError" : e }
10371003 )
10381004
1039- def _validate_xml (self , # pylint: disable=R0913:too-many-arguments disable=R0917:too-many-positional-arguments
1040- xml_file_path : Path ,
1041- xsd_file_path : Optional [Path ] = None ,
1042- base_url : Optional [str ] = None ,
1043- error_facets : Optional [ List [str ] ] = None ,
1044- pre_parse : Optional [bool ] = True
1045- ) -> Tuple [
1046- bool , Optional [
1047- List [ dict [str , Any ] ]
1048- ]
1049- ]:
1005+ def _try_load_initial_schema (
1006+ self ,
1007+ xsd_path : Optional [str | Path ] = None ,
1008+ base_url : Optional [str ] = None
1009+ ) -> None :
1010+ """
1011+ Attempts to resolve, validate, and load a single XSD schema from
1012+ the provided path.
1013+
1014+ This method is invoked during library initialization (i.e.,
1015+ within `__init__`) when an optional `xsd_path` is provided. If a
1016+ path is provided, this method expects the path to resolve to
1017+ exactly one valid`.xsd` file. If successful, the compiled schema
1018+ is returned and stored in `self.schema`.
1019+
1020+ If the path points to a directory, the method searches for a
1021+ single `.xsd` file inside it. If multiple matching files are
1022+ found, or if the file extension is incorrect, an error is
1023+ raised.
1024+
1025+ This method is not intended to be used interactively — it is a
1026+ one-time helper to support declarative schema configuration
1027+ during import of the test library.
1028+
1029+ Args:
1030+
1031+ - xsd_path (str):
1032+ Path to a `.xsd` file or to a directory containing exactly one
1033+ `.xsd` file.
1034+ - base_url (Optional[str]):
1035+ Optional base URL used when parsing the schema, typically to
1036+ resolve includes.
1037+
1038+ Raises:
1039+
1040+ - ValueError:
1041+ If multiple `.xsd` files are found in the provided directory.
1042+ - SystemError:
1043+ If the resolved file does not have a `.xsd` extension or the
1044+ schema fails to load.
1045+ """
1046+ if xsd_path :
1047+ # Try to get a single xsd file from the provided xsd_path.
1048+ xsd_file_path , is_single_xsd_file = (
1049+ self .validator_utils .get_file_paths (
1050+ xsd_path , 'xsd'
1051+ )
1052+ )
1053+ # We need (a path to) a single xsd file.
1054+ if not is_single_xsd_file :
1055+ raise ValueError (
1056+ f"Got multiple xsd files: { xsd_file_path } ."
1057+ )
1058+ # Handle incorrect file extension.
1059+ if xsd_file_path [0 ].suffix != '.xsd' :
1060+ # Raise a load error.
1061+ raise SystemError (
1062+ f"ValueError: { xsd_file_path [0 ]} is not an XSD file."
1063+ )
1064+ # Try to load the provided XSD file.
1065+ result = self ._load_schema (xsd_file_path [0 ], base_url )
1066+ if result .success :
1067+ # Set the loaded XSD file as default schema.
1068+ logger .info (
1069+ f"Schema '{ self .schema .name } ' set." , # type: ignore
1070+ also_console = True )
1071+ return result .value
1072+ # Or report the load error.
1073+ raise SystemError (
1074+ f"Loading of schema failed: { result .error } "
1075+ )
1076+ # Or inform the user on what to do.
1077+ logger .info (
1078+ "No XSD schema set: provide schema(s) during keyword calls." ,
1079+ also_console = True
1080+ )
1081+ # And explicitly flag the schema attr as None.
1082+ return None
1083+
1084+ def _validate_xml ( # pylint: disable=R0913:too-many-arguments disable=R0917:too-many-positional-arguments
1085+ self ,
1086+ xml_file_path : Path ,
1087+ xsd_file_path : Optional [Path ] = None ,
1088+ base_url : Optional [str ] = None ,
1089+ error_facets : Optional [ List [str ] ] = None ,
1090+ pre_parse : Optional [bool ] = True
1091+ ) -> Tuple [
1092+ bool ,
1093+ Optional [List [dict [str , Any ]]]
1094+ ]:
10501095 """
10511096 Validates an XML file against the currently loaded or provided
10521097 XSD schema.
@@ -1259,9 +1304,7 @@ def get_error_facets(self) -> List[str]:
12591304 return self .error_facets
12601305
12611306 @keyword
1262- def get_schema (
1263- self ,
1264- return_schema_name : bool = True
1307+ def get_schema (self ,return_schema_name : bool = True
12651308 ) -> Optional [str | XMLSchema ]:
12661309 """
12671310 .. raw:: html
0 commit comments