diff --git a/misc/config_tools/scenario_config/elementpath_overlay.py b/misc/config_tools/scenario_config/elementpath_overlay.py index d773bf587..5178db3bd 100644 --- a/misc/config_tools/scenario_config/elementpath_overlay.py +++ b/misc/config_tools/scenario_config/elementpath_overlay.py @@ -16,7 +16,10 @@ BaseParser = elementpath.XPath2Parser class CustomParser(BaseParser): SYMBOLS = BaseParser.SYMBOLS | { # Bit-wise operations - 'bitwise-and' + 'bitwise-and', + + 'has', + 'duplicate-values', } method = CustomParser.method @@ -53,6 +56,34 @@ def evaluate(self, context=None): return aux(OPERATORS_MAP[self.symbol]) +@method(function('has', nargs=2)) +def evaluate_has_function(self, context=None): + arg2 = self.get_argument(context, index=1, cls=str) + for item in self[0].select(context): + value = self.data_value(item) + if value == arg2: + return True + return False + +@method(function('duplicate-values', nargs=1)) +def select_duplicate_values_function(self, context=None): + def duplicate_values(): + results = [] + reported = [] + for item in self[0].select(context): + value = self.data_value(item) + if context is not None: + context.item = value + + if value in results: + if value not in reported: + yield value + reported.append(value) + else: + results.append(value) + + yield from duplicate_values() + ### # Collection of counter examples diff --git a/misc/config_tools/scenario_config/validator.py b/misc/config_tools/scenario_config/validator.py index 9441287da..b1f479f8c 100755 --- a/misc/config_tools/scenario_config/validator.py +++ b/misc/config_tools/scenario_config/validator.py @@ -101,7 +101,7 @@ class ScenarioValidator: @staticmethod def format_paths(unified_node, parent_map, report_on, variables): - elems = elementpath.select(unified_node, report_on, variables = variables) + elems = elementpath.select(unified_node, report_on, variables = variables, parser = elementpath.XPath2Parser) paths = [] for elem in elems: path = [] @@ -156,7 +156,7 @@ class ScenarioValidator: expr_regex = re.compile("{[^{}]*}") exprs = set(expr_regex.findall(description)) for expr in exprs: - result = elementpath.select(unified_node, expr.strip("{}"), variables = variables) + result = elementpath.select(unified_node, expr.strip("{}"), variables = variables, parser = elementpath.XPath2Parser) if isinstance(result, list): if len(result) == 1: value = format_node(result[0]) diff --git a/misc/config_tools/schema/datachecks.xsd b/misc/config_tools/schema/datachecks.xsd index 14222497a..f8c934eda 100644 --- a/misc/config_tools/schema/datachecks.xsd +++ b/misc/config_tools/schema/datachecks.xsd @@ -11,6 +11,7 @@ +