Source code for src.xmlChecks.timingAttributeCheck

# SPDX-FileCopyrightText: Copyright © 2026 BBC
#
# SPDX-License-Identifier: BSD-3-Clause

from src.validationLogging.validationCodes import ValidationCode
from src.validationLogging.validationLogger import ValidationLogger
from xml.etree.ElementTree import Element
from src.xmlUtils import xmlIdAttr
from .xmlCheck import XmlCheck

timing_attr_keys = set([
    'begin',
    'end',
    'dur'
])


[docs] def getTimingAttributes( el: Element ) -> set: attr_key_set = set(el.keys()) return attr_key_set.intersection(timing_attr_keys)
[docs] def pushParentTimingAttributes( timing_attributes: set, context: dict ) -> None: parent_timing_stack = context.get('parent_timing', []) parent_timing_stack.append(timing_attributes) context['parent_timing'] = parent_timing_stack return
[docs] def getParentTimingAttributes( context: dict ) -> set: parent_timing_stack = context.get('parent_timing', []) if len(parent_timing_stack) == 0: return set() return parent_timing_stack[-1]
[docs] def popParentTimingAttributes( context: dict ) -> set: parent_timing_stack = context.get('parent_timing', []) return parent_timing_stack.pop()
[docs] class noTimingAttributeCheck(XmlCheck): """ Checks there are no timing attributes on the input element """
[docs] def run( self, input: Element, context: dict, validation_results: ValidationLogger) -> bool: valid = True timing_attributes = list(sorted(getTimingAttributes(input))) if len(timing_attributes) > 0: valid = False validation_results.error( location='{} element xml:id {}' .format( input.tag, input.get(xmlIdAttr, 'omitted')), message='Prohibited timing attributes {} present' .format(timing_attributes), code=ValidationCode.ebuttd_timing_attribute_constraint ) return valid
[docs] class noNestedTimedElementsCheck(XmlCheck): """ Checks for nested elements that have timing attributes """
[docs] def run( self, input: Element, context: dict, validation_results: ValidationLogger) -> bool: valid = True timing_attributes = getTimingAttributes(input) parent_timing_attributes = \ getParentTimingAttributes(context=context) if len(timing_attributes) > 0 \ and len(parent_timing_attributes) > 0: valid = False # TODO: get the parent element details to improve the location # validation_results.error( # location='{}@xml:id {}/{} element'.format( # parent_el.tag, # parent_el.get(xmlIdAttr, 'omitted'), # input.tag), validation_results.error( location='{} element'.format( input.tag), message='Nested elements with timing attributes prohibited', code=ValidationCode.ebuttd_nested_timing_constraint ) return valid