[{"data":1,"prerenderedAt":69},["Reactive",2],{"blog-post-markdown-table-data-validation-quality-assurance-complete-guide":3},{"slug":4,"title":5,"description":6,"excerpt":7,"date":8,"category":9,"author":10,"keywords":11,"readingMinutes":12,"html":13,"headings":14,"tools":43,"related":44},"markdown-table-data-validation-quality-assurance-complete-guide","Markdown Table Data Validation and Quality Assurance: Complete Guide for Automated Table Content Verification","Master comprehensive table data validation techniques in Markdown for automated quality assurance, content verification, and structural integrity checking. Learn advanced validation patterns and automated testing workflows.","Markdown table data validation and quality assurance ensure accurate, consistent, and reliable table content across documentation systems through automated verification, structural integrity…","2025-11-09","Tutorial","Matthew Rathbone","markdown table validation, data quality assurance, table content verification, automated markdown testing, table structure validation, data integrity checking, markdown quality control, table validation tools",22,"\u003Cp>Markdown table data validation and quality assurance ensure accurate, consistent, and reliable table content across documentation systems through automated verification, structural integrity checking, and comprehensive validation workflows. While basic Markdown tables provide functional data presentation, implementing robust validation systems prevents data corruption, maintains formatting consistency, and enforces content standards that scale across large documentation projects and collaborative environments.\u003C/p>\n\u003Ch2 id=\"why-implement-table-data-validation\">Why Implement Table Data Validation?\u003C/h2>\n\u003Cp>Professional table validation provides essential benefits for documentation quality:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Data Integrity\u003C/strong>: Automated validation prevents incorrect or malformed data from reaching production\u003C/li>\n\u003Cli>\u003Cstrong>Consistency Enforcement\u003C/strong>: Standardized validation rules ensure uniform table formatting and content patterns\u003C/li>\n\u003Cli>\u003Cstrong>Error Prevention\u003C/strong>: Early detection of structural issues, formatting problems, and content inconsistencies\u003C/li>\n\u003Cli>\u003Cstrong>Quality Assurance\u003C/strong>: Systematic verification processes maintain professional documentation standards\u003C/li>\n\u003Cli>\u003Cstrong>Scalability\u003C/strong>: Automated validation enables quality control across large documentation repositories\u003C/li>\n\u003Cli>\u003Cstrong>Collaboration Support\u003C/strong>: Validation rules provide clear guidelines for multiple contributors\u003C/li>\n\u003C/ul>\n\u003Ch2 id=\"foundation-table-validation-concepts\">Foundation Table Validation Concepts\u003C/h2>\n\u003Ch3 id=\"basic-structure-validation\">Basic Structure Validation\u003C/h3>\n\u003Cp>Understanding fundamental table structure requirements:\u003C/p>\n\u003Cpre>\u003Ccode class=\"hljs language-markdown\">\u003Cspan class=\"hljs-section\"># Basic Table Structure Requirements\u003C/span>\n\n\u003Cspan class=\"hljs-section\">## Valid Table Components\u003C/span>\n| Component | Required | Description |\n|-----------|----------|-------------|\n| Header Row | Yes | Defines column structure |\n| Separator Row | Yes | Pipe-delimited alignment indicators |\n| Data Rows | Optional | Content rows following header structure |\n| Column Alignment | Optional | Left, center, right alignment markers |\n\n\u003Cspan class=\"hljs-section\">## Common Structural Issues\u003C/span>\n\u003Cspan class=\"hljs-bullet\">1.\u003C/span> \u003Cspan class=\"hljs-strong\">**Missing separators**\u003C/span>: Tables without proper pipe delimiters\n\u003Cspan class=\"hljs-bullet\">2.\u003C/span> \u003Cspan class=\"hljs-strong\">**Column mismatch**\u003C/span>: Data rows with different column counts than headers\n\u003Cspan class=\"hljs-bullet\">3.\u003C/span> \u003Cspan class=\"hljs-strong\">**Malformed alignment**\u003C/span>: Invalid separator row syntax\n\u003Cspan class=\"hljs-bullet\">4.\u003C/span> \u003Cspan class=\"hljs-strong\">**Empty tables**\u003C/span>: Tables without data content\n\u003Cspan class=\"hljs-bullet\">5.\u003C/span> \u003Cspan class=\"hljs-strong\">**Inconsistent spacing**\u003C/span>: Irregular whitespace around delimiters\n\n\u003Cspan class=\"hljs-section\">## Validation Requirements\u003C/span>\n\u003Cspan class=\"hljs-bullet\">-\u003C/span> All rows must have consistent column counts\n\u003Cspan class=\"hljs-bullet\">-\u003C/span> Separator row must match header column structure\n\u003Cspan class=\"hljs-bullet\">-\u003C/span> Alignment markers must use valid syntax (\u003Cspan class=\"hljs-code\">`:---`\u003C/span>, \u003Cspan class=\"hljs-code\">`:---:`\u003C/span>, \u003Cspan class=\"hljs-code\">`---:`\u003C/span>)\n\u003Cspan class=\"hljs-bullet\">-\u003C/span> Tables must contain at least header and separator rows\n\u003Cspan class=\"hljs-bullet\">-\u003C/span> Content must not break Markdown parsing\n\u003C/code>\u003C/pre>\u003Ch3 id=\"content-type-validation\">Content Type Validation\u003C/h3>\n\u003Cp>Implementing content-specific validation rules:\u003C/p>\n\u003Cpre>\u003Ccode class=\"hljs language-markdown\">\u003Cspan class=\"hljs-section\"># Content Type Validation Patterns\u003C/span>\n\n\u003Cspan class=\"hljs-section\">## Numeric Data Validation\u003C/span>\n| Data Type | Pattern | Valid Examples | Invalid Examples |\n|-----------|---------|----------------|------------------|\n| Integer | \u003Cspan class=\"hljs-code\">`^-?\\d+$`\u003C/span> | 42, -17, 0 | 3.14, abc, 42.0 |\n| Decimal | \u003Cspan class=\"hljs-code\">`^-?\\d+\\.\\d+$`\u003C/span> | 3.14, -2.5 | 42, abc, . |\n| Currency | \u003Cspan class=\"hljs-code\">`^\\$[\\d,]+\\.?\\d{0,2}$`\u003C/span> | $1,234.56, $42 | 1234, €50 |\n| Percentage | \u003Cspan class=\"hljs-code\">`^\\d+\\.?\\d*%$`\u003C/span> | 25%, 33.33% | 25, 0.25 |\n\n\u003Cspan class=\"hljs-section\">## Date and Time Validation\u003C/span>\n| Format | Pattern | Valid Examples | Invalid Examples |\n|--------|---------|----------------|------------------|\n| ISO Date | \u003Cspan class=\"hljs-code\">`^\\d{4}-\\d{2}-\\d{2}$`\u003C/span> | 2025-11-09 | 11/09/2025, Nov 9 |\n| US Date | \u003Cspan class=\"hljs-code\">`^\\d{1,2}/\\d{1,2}/\\d{4}$`\u003C/span> | 11/9/2025 | 2025-11-09 |\n| Time | \u003Cspan class=\"hljs-code\">`^\\d{1,2}:\\d{2}(:\\d{2})?$`\u003C/span> | 14:30, 2:45:10 | 14:30:00 PM |\n| DateTime | ISO + T + Time | 2025-11-09T14:30:00 | Invalid combos |\n\n\u003Cspan class=\"hljs-section\">## Text Content Validation\u003C/span>\n| Rule Type | Description | Example Pattern |\n|-----------|-------------|-----------------|\n| Length Limits | Min/max character restrictions | 1-50 characters |\n| Required Fields | Non-empty content validation | Not null/blank |\n| Format Patterns | Specific text structure | Email, URL, ID formats |\n| Allowed Values | Enumerated valid options | Status: Active/Inactive |\n\u003C/code>\u003C/pre>\u003Ch2 id=\"advanced-validation-implementation\">Advanced Validation Implementation\u003C/h2>\n\u003Ch3 id=\"python-table-validator-framework\">Python Table Validator Framework\u003C/h3>\n\u003Cp>Comprehensive validation system for Markdown tables:\u003C/p>\n\u003Cpre>\u003Ccode class=\"hljs language-python\">\u003Cspan class=\"hljs-comment\"># table_validator.py - Advanced Markdown table validation framework\u003C/span>\n\u003Cspan class=\"hljs-keyword\">import\u003C/span> re\n\u003Cspan class=\"hljs-keyword\">import\u003C/span> json\n\u003Cspan class=\"hljs-keyword\">from\u003C/span> typing \u003Cspan class=\"hljs-keyword\">import\u003C/span> \u003Cspan class=\"hljs-type\">Dict\u003C/span>, \u003Cspan class=\"hljs-type\">List\u003C/span>, \u003Cspan class=\"hljs-type\">Optional\u003C/span>, \u003Cspan class=\"hljs-type\">Any\u003C/span>, \u003Cspan class=\"hljs-type\">Union\u003C/span>, \u003Cspan class=\"hljs-type\">Callable\u003C/span>\n\u003Cspan class=\"hljs-keyword\">from\u003C/span> datetime \u003Cspan class=\"hljs-keyword\">import\u003C/span> datetime\n\u003Cspan class=\"hljs-keyword\">from\u003C/span> enum \u003Cspan class=\"hljs-keyword\">import\u003C/span> Enum\n\u003Cspan class=\"hljs-keyword\">import\u003C/span> validators\n\u003Cspan class=\"hljs-keyword\">from\u003C/span> pathlib \u003Cspan class=\"hljs-keyword\">import\u003C/span> Path\n\u003Cspan class=\"hljs-keyword\">import\u003C/span> pandas \u003Cspan class=\"hljs-keyword\">as\u003C/span> pd\n\n\u003Cspan class=\"hljs-keyword\">class\u003C/span> \u003Cspan class=\"hljs-title class_\">ValidationSeverity\u003C/span>(\u003Cspan class=\"hljs-title class_ inherited__\">Enum\u003C/span>):\n    ERROR = \u003Cspan class=\"hljs-string\">&quot;error&quot;\u003C/span>\n    WARNING = \u003Cspan class=\"hljs-string\">&quot;warning&quot;\u003C/span> \n    INFO = \u003Cspan class=\"hljs-string\">&quot;info&quot;\u003C/span>\n\n\u003Cspan class=\"hljs-keyword\">class\u003C/span> \u003Cspan class=\"hljs-title class_\">ValidationResult\u003C/span>:\n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">__init__\u003C/span>(\u003Cspan class=\"hljs-params\">self, severity: ValidationSeverity, message: \u003Cspan class=\"hljs-built_in\">str\u003C/span>, \n                 row: \u003Cspan class=\"hljs-type\">Optional\u003C/span>[\u003Cspan class=\"hljs-built_in\">int\u003C/span>] = \u003Cspan class=\"hljs-literal\">None\u003C/span>, column: \u003Cspan class=\"hljs-type\">Optional\u003C/span>[\u003Cspan class=\"hljs-built_in\">str\u003C/span>] = \u003Cspan class=\"hljs-literal\">None\u003C/span>,\n                 value: \u003Cspan class=\"hljs-type\">Optional\u003C/span>[\u003Cspan class=\"hljs-built_in\">str\u003C/span>] = \u003Cspan class=\"hljs-literal\">None\u003C/span>\u003C/span>):\n        self.severity = severity\n        self.message = message\n        self.row = row\n        self.column = column\n        self.value = value\n        self.timestamp = datetime.now()\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">to_dict\u003C/span>(\u003Cspan class=\"hljs-params\">self\u003C/span>) -&gt; \u003Cspan class=\"hljs-type\">Dict\u003C/span>:\n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> {\n            \u003Cspan class=\"hljs-string\">&#x27;severity&#x27;\u003C/span>: self.severity.value,\n            \u003Cspan class=\"hljs-string\">&#x27;message&#x27;\u003C/span>: self.message,\n            \u003Cspan class=\"hljs-string\">&#x27;row&#x27;\u003C/span>: self.row,\n            \u003Cspan class=\"hljs-string\">&#x27;column&#x27;\u003C/span>: self.column,\n            \u003Cspan class=\"hljs-string\">&#x27;value&#x27;\u003C/span>: self.value,\n            \u003Cspan class=\"hljs-string\">&#x27;timestamp&#x27;\u003C/span>: self.timestamp.isoformat()\n        }\n\n\u003Cspan class=\"hljs-keyword\">class\u003C/span> \u003Cspan class=\"hljs-title class_\">TableValidator\u003C/span>:\n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">__init__\u003C/span>(\u003Cspan class=\"hljs-params\">self, schema: \u003Cspan class=\"hljs-type\">Optional\u003C/span>[\u003Cspan class=\"hljs-type\">Dict\u003C/span>] = \u003Cspan class=\"hljs-literal\">None\u003C/span>\u003C/span>):\n        self.schema = schema \u003Cspan class=\"hljs-keyword\">or\u003C/span> {}\n        self.results: \u003Cspan class=\"hljs-type\">List\u003C/span>[ValidationResult] = []\n        self.custom_validators: \u003Cspan class=\"hljs-type\">Dict\u003C/span>[\u003Cspan class=\"hljs-built_in\">str\u003C/span>, \u003Cspan class=\"hljs-type\">Callable\u003C/span>] = {}\n        \n        \u003Cspan class=\"hljs-comment\"># Built-in validation patterns\u003C/span>\n        self.patterns = {\n            \u003Cspan class=\"hljs-string\">&#x27;integer&#x27;\u003C/span>: re.\u003Cspan class=\"hljs-built_in\">compile\u003C/span>(\u003Cspan class=\"hljs-string\">r&#x27;^-?\\d+$&#x27;\u003C/span>),\n            \u003Cspan class=\"hljs-string\">&#x27;decimal&#x27;\u003C/span>: re.\u003Cspan class=\"hljs-built_in\">compile\u003C/span>(\u003Cspan class=\"hljs-string\">r&#x27;^-?\\d+\\.\\d+$&#x27;\u003C/span>),\n            \u003Cspan class=\"hljs-string\">&#x27;currency&#x27;\u003C/span>: re.\u003Cspan class=\"hljs-built_in\">compile\u003C/span>(\u003Cspan class=\"hljs-string\">r&#x27;^\\$[\\d,]+\\.?\\d{0,2}$&#x27;\u003C/span>),\n            \u003Cspan class=\"hljs-string\">&#x27;percentage&#x27;\u003C/span>: re.\u003Cspan class=\"hljs-built_in\">compile\u003C/span>(\u003Cspan class=\"hljs-string\">r&#x27;^\\d+\\.?\\d*%$&#x27;\u003C/span>),\n            \u003Cspan class=\"hljs-string\">&#x27;iso_date&#x27;\u003C/span>: re.\u003Cspan class=\"hljs-built_in\">compile\u003C/span>(\u003Cspan class=\"hljs-string\">r&#x27;^\\d{4}-\\d{2}-\\d{2}$&#x27;\u003C/span>),\n            \u003Cspan class=\"hljs-string\">&#x27;us_date&#x27;\u003C/span>: re.\u003Cspan class=\"hljs-built_in\">compile\u003C/span>(\u003Cspan class=\"hljs-string\">r&#x27;^\\d{1,2}/\\d{1,2}/\\d{4}$&#x27;\u003C/span>),\n            \u003Cspan class=\"hljs-string\">&#x27;time&#x27;\u003C/span>: re.\u003Cspan class=\"hljs-built_in\">compile\u003C/span>(\u003Cspan class=\"hljs-string\">r&#x27;^\\d{1,2}:\\d{2}(:\\d{2})?$&#x27;\u003C/span>),\n            \u003Cspan class=\"hljs-string\">&#x27;email&#x27;\u003C/span>: re.\u003Cspan class=\"hljs-built_in\">compile\u003C/span>(\u003Cspan class=\"hljs-string\">r&#x27;^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$&#x27;\u003C/span>),\n            \u003Cspan class=\"hljs-string\">&#x27;url&#x27;\u003C/span>: re.\u003Cspan class=\"hljs-built_in\">compile\u003C/span>(\u003Cspan class=\"hljs-string\">r&#x27;^https?://[^\\s/$.?#].[^\\s]*$&#x27;\u003C/span>),\n            \u003Cspan class=\"hljs-string\">&#x27;phone&#x27;\u003C/span>: re.\u003Cspan class=\"hljs-built_in\">compile\u003C/span>(\u003Cspan class=\"hljs-string\">r&#x27;^\\+?[\\d\\s\\-\\(\\)]+$&#x27;\u003C/span>),\n            \u003Cspan class=\"hljs-string\">&#x27;alphanumeric&#x27;\u003C/span>: re.\u003Cspan class=\"hljs-built_in\">compile\u003C/span>(\u003Cspan class=\"hljs-string\">r&#x27;^[a-zA-Z0-9]+$&#x27;\u003C/span>),\n            \u003Cspan class=\"hljs-string\">&#x27;alpha_only&#x27;\u003C/span>: re.\u003Cspan class=\"hljs-built_in\">compile\u003C/span>(\u003Cspan class=\"hljs-string\">r&#x27;^[a-zA-Z\\s]+$&#x27;\u003C/span>)\n        }\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">register_custom_validator\u003C/span>(\u003Cspan class=\"hljs-params\">self, name: \u003Cspan class=\"hljs-built_in\">str\u003C/span>, validator: \u003Cspan class=\"hljs-type\">Callable\u003C/span>[[\u003Cspan class=\"hljs-built_in\">str\u003C/span>], \u003Cspan class=\"hljs-built_in\">bool\u003C/span>]\u003C/span>):\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Register custom validation function&quot;&quot;&quot;\u003C/span>\n        self.custom_validators[name] = validator\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">validate_table_structure\u003C/span>(\u003Cspan class=\"hljs-params\">self, table_text: \u003Cspan class=\"hljs-built_in\">str\u003C/span>\u003C/span>) -&gt; \u003Cspan class=\"hljs-type\">List\u003C/span>[ValidationResult]:\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Validate basic table structure&quot;&quot;&quot;\u003C/span>\n        results = []\n        lines = table_text.strip().split(\u003Cspan class=\"hljs-string\">&#x27;\\n&#x27;\u003C/span>)\n        \n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-built_in\">len\u003C/span>(lines) &lt; \u003Cspan class=\"hljs-number\">2\u003C/span>:\n            results.append(ValidationResult(\n                ValidationSeverity.ERROR,\n                \u003Cspan class=\"hljs-string\">&quot;Table must have at least header and separator rows&quot;\u003C/span>\n            ))\n            \u003Cspan class=\"hljs-keyword\">return\u003C/span> results\n        \n        \u003Cspan class=\"hljs-comment\"># Parse table lines\u003C/span>\n        table_lines = [line.strip() \u003Cspan class=\"hljs-keyword\">for\u003C/span> line \u003Cspan class=\"hljs-keyword\">in\u003C/span> lines \u003Cspan class=\"hljs-keyword\">if\u003C/span> line.strip()]\n        \n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-keyword\">not\u003C/span> table_lines:\n            results.append(ValidationResult(\n                ValidationSeverity.ERROR,\n                \u003Cspan class=\"hljs-string\">&quot;Table cannot be empty&quot;\u003C/span>\n            ))\n            \u003Cspan class=\"hljs-keyword\">return\u003C/span> results\n        \n        \u003Cspan class=\"hljs-comment\"># Validate header row\u003C/span>\n        header_line = table_lines[\u003Cspan class=\"hljs-number\">0\u003C/span>]\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-keyword\">not\u003C/span> self._is_valid_table_row(header_line):\n            results.append(ValidationResult(\n                ValidationSeverity.ERROR,\n                \u003Cspan class=\"hljs-string\">&quot;Invalid header row format&quot;\u003C/span>,\n                row=\u003Cspan class=\"hljs-number\">1\u003C/span>,\n                value=header_line\n            ))\n        \n        header_columns = self._parse_table_row(header_line)\n        column_count = \u003Cspan class=\"hljs-built_in\">len\u003C/span>(header_columns)\n        \n        \u003Cspan class=\"hljs-comment\"># Validate separator row\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-built_in\">len\u003C/span>(table_lines) &lt; \u003Cspan class=\"hljs-number\">2\u003C/span>:\n            results.append(ValidationResult(\n                ValidationSeverity.ERROR,\n                \u003Cspan class=\"hljs-string\">&quot;Missing separator row&quot;\u003C/span>\n            ))\n            \u003Cspan class=\"hljs-keyword\">return\u003C/span> results\n        \n        separator_line = table_lines[\u003Cspan class=\"hljs-number\">1\u003C/span>]\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-keyword\">not\u003C/span> self._is_valid_separator_row(separator_line):\n            results.append(ValidationResult(\n                ValidationSeverity.ERROR,\n                \u003Cspan class=\"hljs-string\">&quot;Invalid separator row format&quot;\u003C/span>,\n                row=\u003Cspan class=\"hljs-number\">2\u003C/span>,\n                value=separator_line\n            ))\n        \u003Cspan class=\"hljs-keyword\">else\u003C/span>:\n            separator_columns = self._parse_table_row(separator_line)\n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-built_in\">len\u003C/span>(separator_columns) != column_count:\n                results.append(ValidationResult(\n                    ValidationSeverity.ERROR,\n                    \u003Cspan class=\"hljs-string\">f&quot;Separator row column count (\u003Cspan class=\"hljs-subst\">{\u003Cspan class=\"hljs-built_in\">len\u003C/span>(separator_columns)}\u003C/span>) doesn&#x27;t match header (\u003Cspan class=\"hljs-subst\">{column_count}\u003C/span>)&quot;\u003C/span>,\n                    row=\u003Cspan class=\"hljs-number\">2\u003C/span>\n                ))\n        \n        \u003Cspan class=\"hljs-comment\"># Validate data rows\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">for\u003C/span> i, line \u003Cspan class=\"hljs-keyword\">in\u003C/span> \u003Cspan class=\"hljs-built_in\">enumerate\u003C/span>(table_lines[\u003Cspan class=\"hljs-number\">2\u003C/span>:], start=\u003Cspan class=\"hljs-number\">3\u003C/span>):\n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-keyword\">not\u003C/span> self._is_valid_table_row(line):\n                results.append(ValidationResult(\n                    ValidationSeverity.ERROR,\n                    \u003Cspan class=\"hljs-string\">&quot;Invalid table row format&quot;\u003C/span>,\n                    row=i,\n                    value=line\n                ))\n                \u003Cspan class=\"hljs-keyword\">continue\u003C/span>\n            \n            row_columns = self._parse_table_row(line)\n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-built_in\">len\u003C/span>(row_columns) != column_count:\n                results.append(ValidationResult(\n                    ValidationSeverity.WARNING,\n                    \u003Cspan class=\"hljs-string\">f&quot;Row column count (\u003Cspan class=\"hljs-subst\">{\u003Cspan class=\"hljs-built_in\">len\u003C/span>(row_columns)}\u003C/span>) doesn&#x27;t match header (\u003Cspan class=\"hljs-subst\">{column_count}\u003C/span>)&quot;\u003C/span>,\n                    row=i\n                ))\n        \n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> results\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">validate_table_content\u003C/span>(\u003Cspan class=\"hljs-params\">self, table_text: \u003Cspan class=\"hljs-built_in\">str\u003C/span>, schema: \u003Cspan class=\"hljs-type\">Optional\u003C/span>[\u003Cspan class=\"hljs-type\">Dict\u003C/span>] = \u003Cspan class=\"hljs-literal\">None\u003C/span>\u003C/span>) -&gt; \u003Cspan class=\"hljs-type\">List\u003C/span>[ValidationResult]:\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Validate table content against schema&quot;&quot;&quot;\u003C/span>\n        validation_schema = schema \u003Cspan class=\"hljs-keyword\">or\u003C/span> self.schema\n        results = []\n        \n        \u003Cspan class=\"hljs-comment\"># Parse table\u003C/span>\n        table_data = self._parse_table_to_dict(table_text)\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-keyword\">not\u003C/span> table_data:\n            results.append(ValidationResult(\n                ValidationSeverity.ERROR,\n                \u003Cspan class=\"hljs-string\">&quot;Could not parse table data&quot;\u003C/span>\n            ))\n            \u003Cspan class=\"hljs-keyword\">return\u003C/span> results\n        \n        headers = table_data.get(\u003Cspan class=\"hljs-string\">&#x27;headers&#x27;\u003C/span>, [])\n        rows = table_data.get(\u003Cspan class=\"hljs-string\">&#x27;rows&#x27;\u003C/span>, [])\n        \n        \u003Cspan class=\"hljs-comment\"># Validate schema compliance\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> validation_schema:\n            results.extend(self._validate_schema_compliance(headers, rows, validation_schema))\n        \n        \u003Cspan class=\"hljs-comment\"># Validate individual cells\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">for\u003C/span> row_idx, row \u003Cspan class=\"hljs-keyword\">in\u003C/span> \u003Cspan class=\"hljs-built_in\">enumerate\u003C/span>(rows, start=\u003Cspan class=\"hljs-number\">1\u003C/span>):\n            \u003Cspan class=\"hljs-keyword\">for\u003C/span> col_idx, (header, cell_value) \u003Cspan class=\"hljs-keyword\">in\u003C/span> \u003Cspan class=\"hljs-built_in\">enumerate\u003C/span>(\u003Cspan class=\"hljs-built_in\">zip\u003C/span>(headers, row)):\n                cell_results = self._validate_cell_content(\n                    cell_value, header, row_idx + \u003Cspan class=\"hljs-number\">2\u003C/span>, validation_schema\n                )\n                results.extend(cell_results)\n        \n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> results\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">_validate_schema_compliance\u003C/span>(\u003Cspan class=\"hljs-params\">self, headers: \u003Cspan class=\"hljs-type\">List\u003C/span>[\u003Cspan class=\"hljs-built_in\">str\u003C/span>], rows: \u003Cspan class=\"hljs-type\">List\u003C/span>[\u003Cspan class=\"hljs-type\">List\u003C/span>[\u003Cspan class=\"hljs-built_in\">str\u003C/span>]], \n                                  schema: \u003Cspan class=\"hljs-type\">Dict\u003C/span>\u003C/span>) -&gt; \u003Cspan class=\"hljs-type\">List\u003C/span>[ValidationResult]:\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Validate table structure against schema&quot;&quot;&quot;\u003C/span>\n        results = []\n        \n        \u003Cspan class=\"hljs-comment\"># Check required columns\u003C/span>\n        required_columns = schema.get(\u003Cspan class=\"hljs-string\">&#x27;required_columns&#x27;\u003C/span>, [])\n        \u003Cspan class=\"hljs-keyword\">for\u003C/span> required_col \u003Cspan class=\"hljs-keyword\">in\u003C/span> required_columns:\n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> required_col \u003Cspan class=\"hljs-keyword\">not\u003C/span> \u003Cspan class=\"hljs-keyword\">in\u003C/span> headers:\n                results.append(ValidationResult(\n                    ValidationSeverity.ERROR,\n                    \u003Cspan class=\"hljs-string\">f&quot;Required column &#x27;\u003Cspan class=\"hljs-subst\">{required_col}\u003C/span>&#x27; is missing&quot;\u003C/span>\n                ))\n        \n        \u003Cspan class=\"hljs-comment\"># Check column definitions\u003C/span>\n        column_definitions = schema.get(\u003Cspan class=\"hljs-string\">&#x27;columns&#x27;\u003C/span>, {})\n        \u003Cspan class=\"hljs-keyword\">for\u003C/span> header \u003Cspan class=\"hljs-keyword\">in\u003C/span> headers:\n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> header \u003Cspan class=\"hljs-keyword\">in\u003C/span> column_definitions:\n                col_def = column_definitions[header]\n                \n                \u003Cspan class=\"hljs-comment\"># Validate column data type consistency\u003C/span>\n                col_index = headers.index(header)\n                \u003Cspan class=\"hljs-keyword\">for\u003C/span> row_idx, row \u003Cspan class=\"hljs-keyword\">in\u003C/span> \u003Cspan class=\"hljs-built_in\">enumerate\u003C/span>(rows, start=\u003Cspan class=\"hljs-number\">1\u003C/span>):\n                    \u003Cspan class=\"hljs-keyword\">if\u003C/span> col_index &lt; \u003Cspan class=\"hljs-built_in\">len\u003C/span>(row):\n                        cell_value = row[col_index].strip()\n                        \u003Cspan class=\"hljs-keyword\">if\u003C/span> cell_value:  \u003Cspan class=\"hljs-comment\"># Skip empty cells\u003C/span>\n                            type_results = self._validate_data_type(\n                                cell_value, col_def.get(\u003Cspan class=\"hljs-string\">&#x27;type&#x27;\u003C/span>), header, row_idx + \u003Cspan class=\"hljs-number\">2\u003C/span>\n                            )\n                            results.extend(type_results)\n        \n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> results\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">_validate_cell_content\u003C/span>(\u003Cspan class=\"hljs-params\">self, cell_value: \u003Cspan class=\"hljs-built_in\">str\u003C/span>, column: \u003Cspan class=\"hljs-built_in\">str\u003C/span>, row: \u003Cspan class=\"hljs-built_in\">int\u003C/span>, \n                             schema: \u003Cspan class=\"hljs-type\">Optional\u003C/span>[\u003Cspan class=\"hljs-type\">Dict\u003C/span>] = \u003Cspan class=\"hljs-literal\">None\u003C/span>\u003C/span>) -&gt; \u003Cspan class=\"hljs-type\">List\u003C/span>[ValidationResult]:\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Validate individual cell content&quot;&quot;&quot;\u003C/span>\n        results = []\n        cleaned_value = cell_value.strip()\n        \n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-keyword\">not\u003C/span> schema \u003Cspan class=\"hljs-keyword\">or\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;columns&#x27;\u003C/span> \u003Cspan class=\"hljs-keyword\">not\u003C/span> \u003Cspan class=\"hljs-keyword\">in\u003C/span> schema \u003Cspan class=\"hljs-keyword\">or\u003C/span> column \u003Cspan class=\"hljs-keyword\">not\u003C/span> \u003Cspan class=\"hljs-keyword\">in\u003C/span> schema[\u003Cspan class=\"hljs-string\">&#x27;columns&#x27;\u003C/span>]:\n            \u003Cspan class=\"hljs-keyword\">return\u003C/span> results\n        \n        column_def = schema[\u003Cspan class=\"hljs-string\">&#x27;columns&#x27;\u003C/span>][column]\n        \n        \u003Cspan class=\"hljs-comment\"># Required field validation\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> column_def.get(\u003Cspan class=\"hljs-string\">&#x27;required&#x27;\u003C/span>, \u003Cspan class=\"hljs-literal\">False\u003C/span>) \u003Cspan class=\"hljs-keyword\">and\u003C/span> \u003Cspan class=\"hljs-keyword\">not\u003C/span> cleaned_value:\n            results.append(ValidationResult(\n                ValidationSeverity.ERROR,\n                \u003Cspan class=\"hljs-string\">f&quot;Required field &#x27;\u003Cspan class=\"hljs-subst\">{column}\u003C/span>&#x27; cannot be empty&quot;\u003C/span>,\n                row=row,\n                column=column,\n                value=cleaned_value\n            ))\n            \u003Cspan class=\"hljs-keyword\">return\u003C/span> results\n        \n        \u003Cspan class=\"hljs-comment\"># Skip validation for empty optional fields\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-keyword\">not\u003C/span> cleaned_value:\n            \u003Cspan class=\"hljs-keyword\">return\u003C/span> results\n        \n        \u003Cspan class=\"hljs-comment\"># Length validation\u003C/span>\n        min_length = column_def.get(\u003Cspan class=\"hljs-string\">&#x27;min_length&#x27;\u003C/span>)\n        max_length = column_def.get(\u003Cspan class=\"hljs-string\">&#x27;max_length&#x27;\u003C/span>)\n        \n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> min_length \u003Cspan class=\"hljs-keyword\">and\u003C/span> \u003Cspan class=\"hljs-built_in\">len\u003C/span>(cleaned_value) &lt; min_length:\n            results.append(ValidationResult(\n                ValidationSeverity.ERROR,\n                \u003Cspan class=\"hljs-string\">f&quot;Value too short (minimum \u003Cspan class=\"hljs-subst\">{min_length}\u003C/span> characters)&quot;\u003C/span>,\n                row=row,\n                column=column,\n                value=cleaned_value\n            ))\n        \n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> max_length \u003Cspan class=\"hljs-keyword\">and\u003C/span> \u003Cspan class=\"hljs-built_in\">len\u003C/span>(cleaned_value) &gt; max_length:\n            results.append(ValidationResult(\n                ValidationSeverity.ERROR,\n                \u003Cspan class=\"hljs-string\">f&quot;Value too long (maximum \u003Cspan class=\"hljs-subst\">{max_length}\u003C/span> characters)&quot;\u003C/span>,\n                row=row,\n                column=column,\n                value=cleaned_value\n            ))\n        \n        \u003Cspan class=\"hljs-comment\"># Allowed values validation\u003C/span>\n        allowed_values = column_def.get(\u003Cspan class=\"hljs-string\">&#x27;allowed_values&#x27;\u003C/span>)\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> allowed_values \u003Cspan class=\"hljs-keyword\">and\u003C/span> cleaned_value \u003Cspan class=\"hljs-keyword\">not\u003C/span> \u003Cspan class=\"hljs-keyword\">in\u003C/span> allowed_values:\n            results.append(ValidationResult(\n                ValidationSeverity.ERROR,\n                \u003Cspan class=\"hljs-string\">f&quot;Value &#x27;\u003Cspan class=\"hljs-subst\">{cleaned_value}\u003C/span>&#x27; not in allowed values: \u003Cspan class=\"hljs-subst\">{allowed_values}\u003C/span>&quot;\u003C/span>,\n                row=row,\n                column=column,\n                value=cleaned_value\n            ))\n        \n        \u003Cspan class=\"hljs-comment\"># Pattern validation\u003C/span>\n        pattern_name = column_def.get(\u003Cspan class=\"hljs-string\">&#x27;pattern&#x27;\u003C/span>)\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> pattern_name:\n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> pattern_name \u003Cspan class=\"hljs-keyword\">in\u003C/span> self.patterns:\n                pattern = self.patterns[pattern_name]\n                \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-keyword\">not\u003C/span> pattern.\u003Cspan class=\"hljs-keyword\">match\u003C/span>(cleaned_value):\n                    results.append(ValidationResult(\n                        ValidationSeverity.ERROR,\n                        \u003Cspan class=\"hljs-string\">f&quot;Value &#x27;\u003Cspan class=\"hljs-subst\">{cleaned_value}\u003C/span>&#x27; doesn&#x27;t match \u003Cspan class=\"hljs-subst\">{pattern_name}\u003C/span> pattern&quot;\u003C/span>,\n                        row=row,\n                        column=column,\n                        value=cleaned_value\n                    ))\n            \u003Cspan class=\"hljs-keyword\">elif\u003C/span> pattern_name \u003Cspan class=\"hljs-keyword\">in\u003C/span> self.custom_validators:\n                validator = self.custom_validators[pattern_name]\n                \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-keyword\">not\u003C/span> validator(cleaned_value):\n                    results.append(ValidationResult(\n                        ValidationSeverity.ERROR,\n                        \u003Cspan class=\"hljs-string\">f&quot;Value &#x27;\u003Cspan class=\"hljs-subst\">{cleaned_value}\u003C/span>&#x27; failed custom validation: \u003Cspan class=\"hljs-subst\">{pattern_name}\u003C/span>&quot;\u003C/span>,\n                        row=row,\n                        column=column,\n                        value=cleaned_value\n                    ))\n        \n        \u003Cspan class=\"hljs-comment\"># Range validation for numeric values\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> column_def.get(\u003Cspan class=\"hljs-string\">&#x27;type&#x27;\u003C/span>) \u003Cspan class=\"hljs-keyword\">in\u003C/span> [\u003Cspan class=\"hljs-string\">&#x27;integer&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;decimal&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;currency&#x27;\u003C/span>]:\n            \u003Cspan class=\"hljs-keyword\">try\u003C/span>:\n                \u003Cspan class=\"hljs-keyword\">if\u003C/span> column_def.get(\u003Cspan class=\"hljs-string\">&#x27;type&#x27;\u003C/span>) == \u003Cspan class=\"hljs-string\">&#x27;currency&#x27;\u003C/span>:\n                    \u003Cspan class=\"hljs-comment\"># Extract numeric value from currency\u003C/span>\n                    numeric_value = \u003Cspan class=\"hljs-built_in\">float\u003C/span>(re.sub(\u003Cspan class=\"hljs-string\">r&#x27;[$,]&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;&#x27;\u003C/span>, cleaned_value))\n                \u003Cspan class=\"hljs-keyword\">elif\u003C/span> column_def.get(\u003Cspan class=\"hljs-string\">&#x27;type&#x27;\u003C/span>) == \u003Cspan class=\"hljs-string\">&#x27;percentage&#x27;\u003C/span>:\n                    numeric_value = \u003Cspan class=\"hljs-built_in\">float\u003C/span>(cleaned_value.rstrip(\u003Cspan class=\"hljs-string\">&#x27;%&#x27;\u003C/span>))\n                \u003Cspan class=\"hljs-keyword\">else\u003C/span>:\n                    numeric_value = \u003Cspan class=\"hljs-built_in\">float\u003C/span>(cleaned_value)\n                \n                min_value = column_def.get(\u003Cspan class=\"hljs-string\">&#x27;min_value&#x27;\u003C/span>)\n                max_value = column_def.get(\u003Cspan class=\"hljs-string\">&#x27;max_value&#x27;\u003C/span>)\n                \n                \u003Cspan class=\"hljs-keyword\">if\u003C/span> min_value \u003Cspan class=\"hljs-keyword\">is\u003C/span> \u003Cspan class=\"hljs-keyword\">not\u003C/span> \u003Cspan class=\"hljs-literal\">None\u003C/span> \u003Cspan class=\"hljs-keyword\">and\u003C/span> numeric_value &lt; min_value:\n                    results.append(ValidationResult(\n                        ValidationSeverity.ERROR,\n                        \u003Cspan class=\"hljs-string\">f&quot;Value \u003Cspan class=\"hljs-subst\">{numeric_value}\u003C/span> is below minimum \u003Cspan class=\"hljs-subst\">{min_value}\u003C/span>&quot;\u003C/span>,\n                        row=row,\n                        column=column,\n                        value=cleaned_value\n                    ))\n                \n                \u003Cspan class=\"hljs-keyword\">if\u003C/span> max_value \u003Cspan class=\"hljs-keyword\">is\u003C/span> \u003Cspan class=\"hljs-keyword\">not\u003C/span> \u003Cspan class=\"hljs-literal\">None\u003C/span> \u003Cspan class=\"hljs-keyword\">and\u003C/span> numeric_value &gt; max_value:\n                    results.append(ValidationResult(\n                        ValidationSeverity.ERROR,\n                        \u003Cspan class=\"hljs-string\">f&quot;Value \u003Cspan class=\"hljs-subst\">{numeric_value}\u003C/span> is above maximum \u003Cspan class=\"hljs-subst\">{max_value}\u003C/span>&quot;\u003C/span>,\n                        row=row,\n                        column=column,\n                        value=cleaned_value\n                    ))\n            \n            \u003Cspan class=\"hljs-keyword\">except\u003C/span> (ValueError, TypeError):\n                \u003Cspan class=\"hljs-comment\"># Already caught by pattern validation\u003C/span>\n                \u003Cspan class=\"hljs-keyword\">pass\u003C/span>\n        \n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> results\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">_validate_data_type\u003C/span>(\u003Cspan class=\"hljs-params\">self, value: \u003Cspan class=\"hljs-built_in\">str\u003C/span>, expected_type: \u003Cspan class=\"hljs-built_in\">str\u003C/span>, column: \u003Cspan class=\"hljs-built_in\">str\u003C/span>, row: \u003Cspan class=\"hljs-built_in\">int\u003C/span>\u003C/span>) -&gt; \u003Cspan class=\"hljs-type\">List\u003C/span>[ValidationResult]:\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Validate data type consistency&quot;&quot;&quot;\u003C/span>\n        results = []\n        \n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-keyword\">not\u003C/span> expected_type \u003Cspan class=\"hljs-keyword\">or\u003C/span> expected_type \u003Cspan class=\"hljs-keyword\">not\u003C/span> \u003Cspan class=\"hljs-keyword\">in\u003C/span> self.patterns:\n            \u003Cspan class=\"hljs-keyword\">return\u003C/span> results\n        \n        pattern = self.patterns[expected_type]\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-keyword\">not\u003C/span> pattern.\u003Cspan class=\"hljs-keyword\">match\u003C/span>(value.strip()):\n            results.append(ValidationResult(\n                ValidationSeverity.ERROR,\n                \u003Cspan class=\"hljs-string\">f&quot;Value &#x27;\u003Cspan class=\"hljs-subst\">{value}\u003C/span>&#x27; doesn&#x27;t match expected type &#x27;\u003Cspan class=\"hljs-subst\">{expected_type}\u003C/span>&#x27;&quot;\u003C/span>,\n                row=row,\n                column=column,\n                value=value\n            ))\n        \n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> results\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">_parse_table_to_dict\u003C/span>(\u003Cspan class=\"hljs-params\">self, table_text: \u003Cspan class=\"hljs-built_in\">str\u003C/span>\u003C/span>) -&gt; \u003Cspan class=\"hljs-type\">Optional\u003C/span>[\u003Cspan class=\"hljs-type\">Dict\u003C/span>]:\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Parse table text into structured data&quot;&quot;&quot;\u003C/span>\n        lines = [line.strip() \u003Cspan class=\"hljs-keyword\">for\u003C/span> line \u003Cspan class=\"hljs-keyword\">in\u003C/span> table_text.strip().split(\u003Cspan class=\"hljs-string\">&#x27;\\n&#x27;\u003C/span>) \u003Cspan class=\"hljs-keyword\">if\u003C/span> line.strip()]\n        \n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-built_in\">len\u003C/span>(lines) &lt; \u003Cspan class=\"hljs-number\">2\u003C/span>:\n            \u003Cspan class=\"hljs-keyword\">return\u003C/span> \u003Cspan class=\"hljs-literal\">None\u003C/span>\n        \n        \u003Cspan class=\"hljs-comment\"># Parse headers\u003C/span>\n        headers = self._parse_table_row(lines[\u003Cspan class=\"hljs-number\">0\u003C/span>])\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-keyword\">not\u003C/span> headers:\n            \u003Cspan class=\"hljs-keyword\">return\u003C/span> \u003Cspan class=\"hljs-literal\">None\u003C/span>\n        \n        \u003Cspan class=\"hljs-comment\"># Skip separator row and parse data rows\u003C/span>\n        data_rows = []\n        \u003Cspan class=\"hljs-keyword\">for\u003C/span> line \u003Cspan class=\"hljs-keyword\">in\u003C/span> lines[\u003Cspan class=\"hljs-number\">2\u003C/span>:]:\n            row_data = self._parse_table_row(line)\n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> row_data:\n                \u003Cspan class=\"hljs-comment\"># Pad or truncate row to match header length\u003C/span>\n                \u003Cspan class=\"hljs-keyword\">while\u003C/span> \u003Cspan class=\"hljs-built_in\">len\u003C/span>(row_data) &lt; \u003Cspan class=\"hljs-built_in\">len\u003C/span>(headers):\n                    row_data.append(\u003Cspan class=\"hljs-string\">&#x27;&#x27;\u003C/span>)\n                row_data = row_data[:\u003Cspan class=\"hljs-built_in\">len\u003C/span>(headers)]\n                data_rows.append(row_data)\n        \n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> {\n            \u003Cspan class=\"hljs-string\">&#x27;headers&#x27;\u003C/span>: headers,\n            \u003Cspan class=\"hljs-string\">&#x27;rows&#x27;\u003C/span>: data_rows\n        }\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">_parse_table_row\u003C/span>(\u003Cspan class=\"hljs-params\">self, line: \u003Cspan class=\"hljs-built_in\">str\u003C/span>\u003C/span>) -&gt; \u003Cspan class=\"hljs-type\">List\u003C/span>[\u003Cspan class=\"hljs-built_in\">str\u003C/span>]:\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Parse a table row into individual cells&quot;&quot;&quot;\u003C/span>\n        \u003Cspan class=\"hljs-comment\"># Remove leading/trailing pipes and split\u003C/span>\n        line = line.strip()\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> line.startswith(\u003Cspan class=\"hljs-string\">&#x27;|&#x27;\u003C/span>):\n            line = line[\u003Cspan class=\"hljs-number\">1\u003C/span>:]\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> line.endswith(\u003Cspan class=\"hljs-string\">&#x27;|&#x27;\u003C/span>):\n            line = line[:-\u003Cspan class=\"hljs-number\">1\u003C/span>]\n        \n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> [cell.strip() \u003Cspan class=\"hljs-keyword\">for\u003C/span> cell \u003Cspan class=\"hljs-keyword\">in\u003C/span> line.split(\u003Cspan class=\"hljs-string\">&#x27;|&#x27;\u003C/span>)]\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">_is_valid_table_row\u003C/span>(\u003Cspan class=\"hljs-params\">self, line: \u003Cspan class=\"hljs-built_in\">str\u003C/span>\u003C/span>) -&gt; \u003Cspan class=\"hljs-built_in\">bool\u003C/span>:\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Check if line is a valid table row&quot;&quot;&quot;\u003C/span>\n        line = line.strip()\n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;|&#x27;\u003C/span> \u003Cspan class=\"hljs-keyword\">in\u003C/span> line \u003Cspan class=\"hljs-keyword\">and\u003C/span> \u003Cspan class=\"hljs-keyword\">not\u003C/span> re.\u003Cspan class=\"hljs-keyword\">match\u003C/span>(\u003Cspan class=\"hljs-string\">r&#x27;^\\s*\\|?\\s*:?-+:?\\s*(\\|\\s*:?-+:?\\s*)*\\|?\\s*$&#x27;\u003C/span>, line)\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">_is_valid_separator_row\u003C/span>(\u003Cspan class=\"hljs-params\">self, line: \u003Cspan class=\"hljs-built_in\">str\u003C/span>\u003C/span>) -&gt; \u003Cspan class=\"hljs-built_in\">bool\u003C/span>:\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Check if line is a valid separator row&quot;&quot;&quot;\u003C/span>\n        line = line.strip()\n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> \u003Cspan class=\"hljs-built_in\">bool\u003C/span>(re.\u003Cspan class=\"hljs-keyword\">match\u003C/span>(\u003Cspan class=\"hljs-string\">r&#x27;^\\s*\\|?\\s*:?-+:?\\s*(\\|\\s*:?-+:?\\s*)*\\|?\\s*$&#x27;\u003C/span>, line))\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">validate_file\u003C/span>(\u003Cspan class=\"hljs-params\">self, file_path: Path, schema_path: \u003Cspan class=\"hljs-type\">Optional\u003C/span>[Path] = \u003Cspan class=\"hljs-literal\">None\u003C/span>\u003C/span>) -&gt; \u003Cspan class=\"hljs-type\">Dict\u003C/span>:\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Validate all tables in a markdown file&quot;&quot;&quot;\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">with\u003C/span> \u003Cspan class=\"hljs-built_in\">open\u003C/span>(file_path, \u003Cspan class=\"hljs-string\">&#x27;r&#x27;\u003C/span>, encoding=\u003Cspan class=\"hljs-string\">&#x27;utf-8&#x27;\u003C/span>) \u003Cspan class=\"hljs-keyword\">as\u003C/span> f:\n            content = f.read()\n        \n        \u003Cspan class=\"hljs-comment\"># Load schema if provided\u003C/span>\n        schema = \u003Cspan class=\"hljs-literal\">None\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> schema_path \u003Cspan class=\"hljs-keyword\">and\u003C/span> schema_path.exists():\n            \u003Cspan class=\"hljs-keyword\">with\u003C/span> \u003Cspan class=\"hljs-built_in\">open\u003C/span>(schema_path, \u003Cspan class=\"hljs-string\">&#x27;r&#x27;\u003C/span>, encoding=\u003Cspan class=\"hljs-string\">&#x27;utf-8&#x27;\u003C/span>) \u003Cspan class=\"hljs-keyword\">as\u003C/span> f:\n                schema = json.load(f)\n        \n        \u003Cspan class=\"hljs-comment\"># Extract tables from markdown content\u003C/span>\n        table_pattern = re.\u003Cspan class=\"hljs-built_in\">compile\u003C/span>(\u003Cspan class=\"hljs-string\">r&#x27;(\\|.*?\\|.*?\\n(?:\\|.*?\\|.*?\\n)*)&#x27;\u003C/span>, re.MULTILINE)\n        tables = table_pattern.findall(content)\n        \n        file_results = {\n            \u003Cspan class=\"hljs-string\">&#x27;file&#x27;\u003C/span>: \u003Cspan class=\"hljs-built_in\">str\u003C/span>(file_path),\n            \u003Cspan class=\"hljs-string\">&#x27;tables_found&#x27;\u003C/span>: \u003Cspan class=\"hljs-built_in\">len\u003C/span>(tables),\n            \u003Cspan class=\"hljs-string\">&#x27;validation_results&#x27;\u003C/span>: [],\n            \u003Cspan class=\"hljs-string\">&#x27;summary&#x27;\u003C/span>: {\n                \u003Cspan class=\"hljs-string\">&#x27;errors&#x27;\u003C/span>: \u003Cspan class=\"hljs-number\">0\u003C/span>,\n                \u003Cspan class=\"hljs-string\">&#x27;warnings&#x27;\u003C/span>: \u003Cspan class=\"hljs-number\">0\u003C/span>,\n                \u003Cspan class=\"hljs-string\">&#x27;info&#x27;\u003C/span>: \u003Cspan class=\"hljs-number\">0\u003C/span>\n            }\n        }\n        \n        \u003Cspan class=\"hljs-keyword\">for\u003C/span> i, table_text \u003Cspan class=\"hljs-keyword\">in\u003C/span> \u003Cspan class=\"hljs-built_in\">enumerate\u003C/span>(tables, \u003Cspan class=\"hljs-number\">1\u003C/span>):\n            \u003Cspan class=\"hljs-comment\"># Validate structure\u003C/span>\n            structure_results = self.validate_table_structure(table_text)\n            \n            \u003Cspan class=\"hljs-comment\"># Validate content if schema available\u003C/span>\n            content_results = []\n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> schema:\n                content_results = self.validate_table_content(table_text, schema)\n            \n            all_results = structure_results + content_results\n            \n            table_result = {\n                \u003Cspan class=\"hljs-string\">&#x27;table_number&#x27;\u003C/span>: i,\n                \u003Cspan class=\"hljs-string\">&#x27;table_text&#x27;\u003C/span>: table_text.strip(),\n                \u003Cspan class=\"hljs-string\">&#x27;validations&#x27;\u003C/span>: [result.to_dict() \u003Cspan class=\"hljs-keyword\">for\u003C/span> result \u003Cspan class=\"hljs-keyword\">in\u003C/span> all_results]\n            }\n            \n            \u003Cspan class=\"hljs-comment\"># Update summary counts\u003C/span>\n            \u003Cspan class=\"hljs-keyword\">for\u003C/span> result \u003Cspan class=\"hljs-keyword\">in\u003C/span> all_results:\n                file_results[\u003Cspan class=\"hljs-string\">&#x27;summary&#x27;\u003C/span>][result.severity.value] += \u003Cspan class=\"hljs-number\">1\u003C/span>\n            \n            file_results[\u003Cspan class=\"hljs-string\">&#x27;validation_results&#x27;\u003C/span>].append(table_result)\n        \n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> file_results\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">generate_validation_report\u003C/span>(\u003Cspan class=\"hljs-params\">self, results: \u003Cspan class=\"hljs-type\">Dict\u003C/span>\u003C/span>) -&gt; \u003Cspan class=\"hljs-built_in\">str\u003C/span>:\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Generate human-readable validation report&quot;&quot;&quot;\u003C/span>\n        report = []\n        report.append(\u003Cspan class=\"hljs-string\">f&quot;# Table Validation Report&quot;\u003C/span>)\n        report.append(\u003Cspan class=\"hljs-string\">f&quot;**File**: \u003Cspan class=\"hljs-subst\">{results[\u003Cspan class=\"hljs-string\">&#x27;file&#x27;\u003C/span>]}\u003C/span>&quot;\u003C/span>)\n        report.append(\u003Cspan class=\"hljs-string\">f&quot;**Tables Found**: \u003Cspan class=\"hljs-subst\">{results[\u003Cspan class=\"hljs-string\">&#x27;tables_found&#x27;\u003C/span>]}\u003C/span>&quot;\u003C/span>)\n        report.append(\u003Cspan class=\"hljs-string\">&quot;&quot;\u003C/span>)\n        \n        summary = results[\u003Cspan class=\"hljs-string\">&#x27;summary&#x27;\u003C/span>]\n        report.append(\u003Cspan class=\"hljs-string\">&quot;## Summary&quot;\u003C/span>)\n        report.append(\u003Cspan class=\"hljs-string\">f&quot;- ❌ Errors: \u003Cspan class=\"hljs-subst\">{summary[\u003Cspan class=\"hljs-string\">&#x27;errors&#x27;\u003C/span>]}\u003C/span>&quot;\u003C/span>)\n        report.append(\u003Cspan class=\"hljs-string\">f&quot;- ⚠️ Warnings: \u003Cspan class=\"hljs-subst\">{summary[\u003Cspan class=\"hljs-string\">&#x27;warnings&#x27;\u003C/span>]}\u003C/span>&quot;\u003C/span>)  \n        report.append(\u003Cspan class=\"hljs-string\">f&quot;- ℹ️ Info: \u003Cspan class=\"hljs-subst\">{summary[\u003Cspan class=\"hljs-string\">&#x27;info&#x27;\u003C/span>]}\u003C/span>&quot;\u003C/span>)\n        report.append(\u003Cspan class=\"hljs-string\">&quot;&quot;\u003C/span>)\n        \n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> summary[\u003Cspan class=\"hljs-string\">&#x27;errors&#x27;\u003C/span>] == \u003Cspan class=\"hljs-number\">0\u003C/span> \u003Cspan class=\"hljs-keyword\">and\u003C/span> summary[\u003Cspan class=\"hljs-string\">&#x27;warnings&#x27;\u003C/span>] == \u003Cspan class=\"hljs-number\">0\u003C/span>:\n            report.append(\u003Cspan class=\"hljs-string\">&quot;✅ **All tables passed validation!**&quot;\u003C/span>)\n            \u003Cspan class=\"hljs-keyword\">return\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;\\n&#x27;\u003C/span>.join(report)\n        \n        report.append(\u003Cspan class=\"hljs-string\">&quot;## Detailed Results&quot;\u003C/span>)\n        report.append(\u003Cspan class=\"hljs-string\">&quot;&quot;\u003C/span>)\n        \n        \u003Cspan class=\"hljs-keyword\">for\u003C/span> table_result \u003Cspan class=\"hljs-keyword\">in\u003C/span> results[\u003Cspan class=\"hljs-string\">&#x27;validation_results&#x27;\u003C/span>]:\n            table_num = table_result[\u003Cspan class=\"hljs-string\">&#x27;table_number&#x27;\u003C/span>]\n            validations = table_result[\u003Cspan class=\"hljs-string\">&#x27;validations&#x27;\u003C/span>]\n            \n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-keyword\">not\u003C/span> validations:\n                report.append(\u003Cspan class=\"hljs-string\">f&quot;### Table \u003Cspan class=\"hljs-subst\">{table_num}\u003C/span> ✅&quot;\u003C/span>)\n                report.append(\u003Cspan class=\"hljs-string\">&quot;No issues found.&quot;\u003C/span>)\n                report.append(\u003Cspan class=\"hljs-string\">&quot;&quot;\u003C/span>)\n                \u003Cspan class=\"hljs-keyword\">continue\u003C/span>\n            \n            report.append(\u003Cspan class=\"hljs-string\">f&quot;### Table \u003Cspan class=\"hljs-subst\">{table_num}\u003C/span>&quot;\u003C/span>)\n            report.append(\u003Cspan class=\"hljs-string\">&quot;```markdown&quot;\u003C/span>)\n            report.append(table_result[\u003Cspan class=\"hljs-string\">&#x27;table_text&#x27;\u003C/span>])\n            report.append(\u003Cspan class=\"hljs-string\">&quot;```&quot;\u003C/span>)\n            report.append(\u003Cspan class=\"hljs-string\">&quot;&quot;\u003C/span>)\n            \n            \u003Cspan class=\"hljs-keyword\">for\u003C/span> validation \u003Cspan class=\"hljs-keyword\">in\u003C/span> validations:\n                severity_icon = {\u003Cspan class=\"hljs-string\">&#x27;error&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;❌&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;warning&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;⚠️&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;info&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;ℹ️&#x27;\u003C/span>}\n                icon = severity_icon.get(validation[\u003Cspan class=\"hljs-string\">&#x27;severity&#x27;\u003C/span>], \u003Cspan class=\"hljs-string\">&#x27;•&#x27;\u003C/span>)\n                \n                location = \u003Cspan class=\"hljs-string\">&quot;&quot;\u003C/span>\n                \u003Cspan class=\"hljs-keyword\">if\u003C/span> validation[\u003Cspan class=\"hljs-string\">&#x27;row&#x27;\u003C/span>]:\n                    location = \u003Cspan class=\"hljs-string\">f&quot; (Row \u003Cspan class=\"hljs-subst\">{validation[\u003Cspan class=\"hljs-string\">&#x27;row&#x27;\u003C/span>]}\u003C/span>&quot;\u003C/span>\n                    \u003Cspan class=\"hljs-keyword\">if\u003C/span> validation[\u003Cspan class=\"hljs-string\">&#x27;column&#x27;\u003C/span>]:\n                        location += \u003Cspan class=\"hljs-string\">f&quot;, Column &#x27;\u003Cspan class=\"hljs-subst\">{validation[\u003Cspan class=\"hljs-string\">&#x27;column&#x27;\u003C/span>]}\u003C/span>&#x27;&quot;\u003C/span>\n                    location += \u003Cspan class=\"hljs-string\">&quot;)&quot;\u003C/span>\n                \n                report.append(\u003Cspan class=\"hljs-string\">f&quot;\u003Cspan class=\"hljs-subst\">{icon}\u003C/span> **\u003Cspan class=\"hljs-subst\">{validation[\u003Cspan class=\"hljs-string\">&#x27;severity&#x27;\u003C/span>].upper()}\u003C/span>**\u003Cspan class=\"hljs-subst\">{location}\u003C/span>: \u003Cspan class=\"hljs-subst\">{validation[\u003Cspan class=\"hljs-string\">&#x27;message&#x27;\u003C/span>]}\u003C/span>&quot;\u003C/span>)\n                \n                \u003Cspan class=\"hljs-keyword\">if\u003C/span> validation[\u003Cspan class=\"hljs-string\">&#x27;value&#x27;\u003C/span>]:\n                    report.append(\u003Cspan class=\"hljs-string\">f&quot;   Value: `\u003Cspan class=\"hljs-subst\">{validation[\u003Cspan class=\"hljs-string\">&#x27;value&#x27;\u003C/span>]}\u003C/span>`&quot;\u003C/span>)\n            \n            report.append(\u003Cspan class=\"hljs-string\">&quot;&quot;\u003C/span>)\n        \n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;\\n&#x27;\u003C/span>.join(report)\n\n\u003Cspan class=\"hljs-comment\"># Example usage and schema definitions\u003C/span>\n\u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">create_sample_schemas\u003C/span>() -&gt; \u003Cspan class=\"hljs-type\">Dict\u003C/span>[\u003Cspan class=\"hljs-built_in\">str\u003C/span>, \u003Cspan class=\"hljs-type\">Dict\u003C/span>]:\n    \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Create sample validation schemas for different use cases&quot;&quot;&quot;\u003C/span>\n    \n    schemas = {\n        \u003Cspan class=\"hljs-string\">&#x27;financial_report&#x27;\u003C/span>: {\n            \u003Cspan class=\"hljs-string\">&#x27;required_columns&#x27;\u003C/span>: [\u003Cspan class=\"hljs-string\">&#x27;Account&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;Q1 2025&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;Q2 2025&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;Q3 2025&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;Q4 2025&#x27;\u003C/span>],\n            \u003Cspan class=\"hljs-string\">&#x27;columns&#x27;\u003C/span>: {\n                \u003Cspan class=\"hljs-string\">&#x27;Account&#x27;\u003C/span>: {\n                    \u003Cspan class=\"hljs-string\">&#x27;type&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;alpha_only&#x27;\u003C/span>,\n                    \u003Cspan class=\"hljs-string\">&#x27;required&#x27;\u003C/span>: \u003Cspan class=\"hljs-literal\">True\u003C/span>,\n                    \u003Cspan class=\"hljs-string\">&#x27;min_length&#x27;\u003C/span>: \u003Cspan class=\"hljs-number\">2\u003C/span>,\n                    \u003Cspan class=\"hljs-string\">&#x27;max_length&#x27;\u003C/span>: \u003Cspan class=\"hljs-number\">50\u003C/span>\n                },\n                \u003Cspan class=\"hljs-string\">&#x27;Q1 2025&#x27;\u003C/span>: {\n                    \u003Cspan class=\"hljs-string\">&#x27;type&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;currency&#x27;\u003C/span>,\n                    \u003Cspan class=\"hljs-string\">&#x27;required&#x27;\u003C/span>: \u003Cspan class=\"hljs-literal\">True\u003C/span>,\n                    \u003Cspan class=\"hljs-string\">&#x27;min_value&#x27;\u003C/span>: -\u003Cspan class=\"hljs-number\">1000000\u003C/span>,\n                    \u003Cspan class=\"hljs-string\">&#x27;max_value&#x27;\u003C/span>: \u003Cspan class=\"hljs-number\">10000000\u003C/span>\n                },\n                \u003Cspan class=\"hljs-string\">&#x27;Q2 2025&#x27;\u003C/span>: {\n                    \u003Cspan class=\"hljs-string\">&#x27;type&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;currency&#x27;\u003C/span>,\n                    \u003Cspan class=\"hljs-string\">&#x27;required&#x27;\u003C/span>: \u003Cspan class=\"hljs-literal\">True\u003C/span>,\n                    \u003Cspan class=\"hljs-string\">&#x27;min_value&#x27;\u003C/span>: -\u003Cspan class=\"hljs-number\">1000000\u003C/span>,\n                    \u003Cspan class=\"hljs-string\">&#x27;max_value&#x27;\u003C/span>: \u003Cspan class=\"hljs-number\">10000000\u003C/span>\n                },\n                \u003Cspan class=\"hljs-string\">&#x27;Q3 2025&#x27;\u003C/span>: {\n                    \u003Cspan class=\"hljs-string\">&#x27;type&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;currency&#x27;\u003C/span>,\n                    \u003Cspan class=\"hljs-string\">&#x27;required&#x27;\u003C/span>: \u003Cspan class=\"hljs-literal\">True\u003C/span>,\n                    \u003Cspan class=\"hljs-string\">&#x27;min_value&#x27;\u003C/span>: -\u003Cspan class=\"hljs-number\">1000000\u003C/span>,\n                    \u003Cspan class=\"hljs-string\">&#x27;max_value&#x27;\u003C/span>: \u003Cspan class=\"hljs-number\">10000000\u003C/span>\n                },\n                \u003Cspan class=\"hljs-string\">&#x27;Q4 2025&#x27;\u003C/span>: {\n                    \u003Cspan class=\"hljs-string\">&#x27;type&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;currency&#x27;\u003C/span>,\n                    \u003Cspan class=\"hljs-string\">&#x27;required&#x27;\u003C/span>: \u003Cspan class=\"hljs-literal\">True\u003C/span>,\n                    \u003Cspan class=\"hljs-string\">&#x27;min_value&#x27;\u003C/span>: -\u003Cspan class=\"hljs-number\">1000000\u003C/span>,\n                    \u003Cspan class=\"hljs-string\">&#x27;max_value&#x27;\u003C/span>: \u003Cspan class=\"hljs-number\">10000000\u003C/span>\n                }\n            }\n        },\n        \n        \u003Cspan class=\"hljs-string\">&#x27;user_directory&#x27;\u003C/span>: {\n            \u003Cspan class=\"hljs-string\">&#x27;required_columns&#x27;\u003C/span>: [\u003Cspan class=\"hljs-string\">&#x27;Name&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;Email&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;Department&#x27;\u003C/span>],\n            \u003Cspan class=\"hljs-string\">&#x27;columns&#x27;\u003C/span>: {\n                \u003Cspan class=\"hljs-string\">&#x27;Name&#x27;\u003C/span>: {\n                    \u003Cspan class=\"hljs-string\">&#x27;type&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;alpha_only&#x27;\u003C/span>,\n                    \u003Cspan class=\"hljs-string\">&#x27;required&#x27;\u003C/span>: \u003Cspan class=\"hljs-literal\">True\u003C/span>,\n                    \u003Cspan class=\"hljs-string\">&#x27;min_length&#x27;\u003C/span>: \u003Cspan class=\"hljs-number\">2\u003C/span>,\n                    \u003Cspan class=\"hljs-string\">&#x27;max_length&#x27;\u003C/span>: \u003Cspan class=\"hljs-number\">100\u003C/span>\n                },\n                \u003Cspan class=\"hljs-string\">&#x27;Email&#x27;\u003C/span>: {\n                    \u003Cspan class=\"hljs-string\">&#x27;type&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;email&#x27;\u003C/span>,\n                    \u003Cspan class=\"hljs-string\">&#x27;required&#x27;\u003C/span>: \u003Cspan class=\"hljs-literal\">True\u003C/span>\n                },\n                \u003Cspan class=\"hljs-string\">&#x27;Department&#x27;\u003C/span>: {\n                    \u003Cspan class=\"hljs-string\">&#x27;type&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;alpha_only&#x27;\u003C/span>,\n                    \u003Cspan class=\"hljs-string\">&#x27;required&#x27;\u003C/span>: \u003Cspan class=\"hljs-literal\">True\u003C/span>,\n                    \u003Cspan class=\"hljs-string\">&#x27;allowed_values&#x27;\u003C/span>: [\u003Cspan class=\"hljs-string\">&#x27;Engineering&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;Marketing&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;Sales&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;Support&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;Finance&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;HR&#x27;\u003C/span>]\n                },\n                \u003Cspan class=\"hljs-string\">&#x27;Phone&#x27;\u003C/span>: {\n                    \u003Cspan class=\"hljs-string\">&#x27;type&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;phone&#x27;\u003C/span>,\n                    \u003Cspan class=\"hljs-string\">&#x27;required&#x27;\u003C/span>: \u003Cspan class=\"hljs-literal\">False\u003C/span>\n                },\n                \u003Cspan class=\"hljs-string\">&#x27;Start Date&#x27;\u003C/span>: {\n                    \u003Cspan class=\"hljs-string\">&#x27;type&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;iso_date&#x27;\u003C/span>,\n                    \u003Cspan class=\"hljs-string\">&#x27;required&#x27;\u003C/span>: \u003Cspan class=\"hljs-literal\">False\u003C/span>\n                },\n                \u003Cspan class=\"hljs-string\">&#x27;Status&#x27;\u003C/span>: {\n                    \u003Cspan class=\"hljs-string\">&#x27;type&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;alpha_only&#x27;\u003C/span>,\n                    \u003Cspan class=\"hljs-string\">&#x27;required&#x27;\u003C/span>: \u003Cspan class=\"hljs-literal\">False\u003C/span>,\n                    \u003Cspan class=\"hljs-string\">&#x27;allowed_values&#x27;\u003C/span>: [\u003Cspan class=\"hljs-string\">&#x27;Active&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;Inactive&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;On Leave&#x27;\u003C/span>]\n                }\n            }\n        },\n        \n        \u003Cspan class=\"hljs-string\">&#x27;product_catalog&#x27;\u003C/span>: {\n            \u003Cspan class=\"hljs-string\">&#x27;required_columns&#x27;\u003C/span>: [\u003Cspan class=\"hljs-string\">&#x27;Product Name&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;Price&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;Category&#x27;\u003C/span>],\n            \u003Cspan class=\"hljs-string\">&#x27;columns&#x27;\u003C/span>: {\n                \u003Cspan class=\"hljs-string\">&#x27;Product Name&#x27;\u003C/span>: {\n                    \u003Cspan class=\"hljs-string\">&#x27;required&#x27;\u003C/span>: \u003Cspan class=\"hljs-literal\">True\u003C/span>,\n                    \u003Cspan class=\"hljs-string\">&#x27;min_length&#x27;\u003C/span>: \u003Cspan class=\"hljs-number\">1\u003C/span>,\n                    \u003Cspan class=\"hljs-string\">&#x27;max_length&#x27;\u003C/span>: \u003Cspan class=\"hljs-number\">200\u003C/span>\n                },\n                \u003Cspan class=\"hljs-string\">&#x27;Price&#x27;\u003C/span>: {\n                    \u003Cspan class=\"hljs-string\">&#x27;type&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;currency&#x27;\u003C/span>,\n                    \u003Cspan class=\"hljs-string\">&#x27;required&#x27;\u003C/span>: \u003Cspan class=\"hljs-literal\">True\u003C/span>,\n                    \u003Cspan class=\"hljs-string\">&#x27;min_value&#x27;\u003C/span>: \u003Cspan class=\"hljs-number\">0\u003C/span>,\n                    \u003Cspan class=\"hljs-string\">&#x27;max_value&#x27;\u003C/span>: \u003Cspan class=\"hljs-number\">100000\u003C/span>\n                },\n                \u003Cspan class=\"hljs-string\">&#x27;Category&#x27;\u003C/span>: {\n                    \u003Cspan class=\"hljs-string\">&#x27;required&#x27;\u003C/span>: \u003Cspan class=\"hljs-literal\">True\u003C/span>,\n                    \u003Cspan class=\"hljs-string\">&#x27;allowed_values&#x27;\u003C/span>: [\u003Cspan class=\"hljs-string\">&#x27;Electronics&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;Clothing&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;Books&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;Home&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;Sports&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;Other&#x27;\u003C/span>]\n                },\n                \u003Cspan class=\"hljs-string\">&#x27;SKU&#x27;\u003C/span>: {\n                    \u003Cspan class=\"hljs-string\">&#x27;type&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;alphanumeric&#x27;\u003C/span>,\n                    \u003Cspan class=\"hljs-string\">&#x27;required&#x27;\u003C/span>: \u003Cspan class=\"hljs-literal\">True\u003C/span>,\n                    \u003Cspan class=\"hljs-string\">&#x27;min_length&#x27;\u003C/span>: \u003Cspan class=\"hljs-number\">3\u003C/span>,\n                    \u003Cspan class=\"hljs-string\">&#x27;max_length&#x27;\u003C/span>: \u003Cspan class=\"hljs-number\">20\u003C/span>\n                },\n                \u003Cspan class=\"hljs-string\">&#x27;Stock&#x27;\u003C/span>: {\n                    \u003Cspan class=\"hljs-string\">&#x27;type&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;integer&#x27;\u003C/span>,\n                    \u003Cspan class=\"hljs-string\">&#x27;required&#x27;\u003C/span>: \u003Cspan class=\"hljs-literal\">False\u003C/span>,\n                    \u003Cspan class=\"hljs-string\">&#x27;min_value&#x27;\u003C/span>: \u003Cspan class=\"hljs-number\">0\u003C/span>,\n                    \u003Cspan class=\"hljs-string\">&#x27;max_value&#x27;\u003C/span>: \u003Cspan class=\"hljs-number\">10000\u003C/span>\n                },\n                \u003Cspan class=\"hljs-string\">&#x27;Rating&#x27;\u003C/span>: {\n                    \u003Cspan class=\"hljs-string\">&#x27;type&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;decimal&#x27;\u003C/span>,\n                    \u003Cspan class=\"hljs-string\">&#x27;required&#x27;\u003C/span>: \u003Cspan class=\"hljs-literal\">False\u003C/span>,\n                    \u003Cspan class=\"hljs-string\">&#x27;min_value&#x27;\u003C/span>: \u003Cspan class=\"hljs-number\">1.0\u003C/span>,\n                    \u003Cspan class=\"hljs-string\">&#x27;max_value&#x27;\u003C/span>: \u003Cspan class=\"hljs-number\">5.0\u003C/span>\n                }\n            }\n        }\n    }\n    \n    \u003Cspan class=\"hljs-keyword\">return\u003C/span> schemas\n\n\u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">demonstrate_table_validation\u003C/span>():\n    \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Demonstrate comprehensive table validation&quot;&quot;&quot;\u003C/span>\n    \n    \u003Cspan class=\"hljs-comment\"># Sample tables with various issues\u003C/span>\n    test_tables = {\n        \u003Cspan class=\"hljs-string\">&#x27;valid_financial&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;&#x27;&#x27;\n| Account | Q1 2025 | Q2 2025 | Q3 2025 | Q4 2025 |\n|---------|---------|---------|---------|---------|\n| Revenue | $125,000 | $135,000 | $142,000 | $155,000 |\n| Expenses | $85,000 | $92,000 | $98,000 | $105,000 |\n| Profit | $40,000 | $43,000 | $44,000 | $50,000 |\n        &#x27;&#x27;&#x27;\u003C/span>,\n        \n        \u003Cspan class=\"hljs-string\">&#x27;invalid_structure&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;&#x27;&#x27;\n| Name | Email | Department |\n|------|-------|------------|\n| John Doe | john@example.com | Engineering | Extra Column |\n| Jane Smith | invalid-email | Marketing |\n| | missing@email.com | Invalid Dept |\n        &#x27;&#x27;&#x27;\u003C/span>,\n        \n        \u003Cspan class=\"hljs-string\">&#x27;mixed_issues&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;&#x27;&#x27;\n| Product Name | Price | Category | Stock |\n|-------------|--------|-----------|--------|\n| Valid Product | $29.99 | Electronics | 50 |\n| | $invalid | Unknown Category | -5 |\n| Overpriced Item | $150000 | Books | 9999999 |\n        &#x27;&#x27;&#x27;\u003C/span>\n    }\n    \n    \u003Cspan class=\"hljs-comment\"># Create validator with schemas\u003C/span>\n    schemas = create_sample_schemas()\n    validator = TableValidator()\n    \n    \u003Cspan class=\"hljs-built_in\">print\u003C/span>(\u003Cspan class=\"hljs-string\">&quot;Table Validation Demonstration&quot;\u003C/span>)\n    \u003Cspan class=\"hljs-built_in\">print\u003C/span>(\u003Cspan class=\"hljs-string\">&quot;=&quot;\u003C/span> * \u003Cspan class=\"hljs-number\">50\u003C/span>)\n    \n    \u003Cspan class=\"hljs-keyword\">for\u003C/span> table_name, table_text \u003Cspan class=\"hljs-keyword\">in\u003C/span> test_tables.items():\n        \u003Cspan class=\"hljs-built_in\">print\u003C/span>(\u003Cspan class=\"hljs-string\">f&quot;\\n### Validating: \u003Cspan class=\"hljs-subst\">{table_name}\u003C/span>&quot;\u003C/span>)\n        \u003Cspan class=\"hljs-built_in\">print\u003C/span>(\u003Cspan class=\"hljs-string\">&quot;Table content:&quot;\u003C/span>)\n        \u003Cspan class=\"hljs-built_in\">print\u003C/span>(table_text.strip())\n        \u003Cspan class=\"hljs-built_in\">print\u003C/span>()\n        \n        \u003Cspan class=\"hljs-comment\"># Structural validation\u003C/span>\n        structure_results = validator.validate_table_structure(table_text)\n        \u003Cspan class=\"hljs-built_in\">print\u003C/span>(\u003Cspan class=\"hljs-string\">&quot;Structure Validation:&quot;\u003C/span>)\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> structure_results:\n            \u003Cspan class=\"hljs-keyword\">for\u003C/span> result \u003Cspan class=\"hljs-keyword\">in\u003C/span> structure_results:\n                severity_icon = {\u003Cspan class=\"hljs-string\">&#x27;error&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;❌&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;warning&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;⚠️&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;info&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;ℹ️&#x27;\u003C/span>}\n                icon = severity_icon.get(result.severity.value, \u003Cspan class=\"hljs-string\">&#x27;•&#x27;\u003C/span>)\n                \u003Cspan class=\"hljs-built_in\">print\u003C/span>(\u003Cspan class=\"hljs-string\">f&quot;  \u003Cspan class=\"hljs-subst\">{icon}\u003C/span> \u003Cspan class=\"hljs-subst\">{result.message}\u003C/span>&quot;\u003C/span>)\n                \u003Cspan class=\"hljs-keyword\">if\u003C/span> result.row:\n                    \u003Cspan class=\"hljs-built_in\">print\u003C/span>(\u003Cspan class=\"hljs-string\">f&quot;      Row \u003Cspan class=\"hljs-subst\">{result.row}\u003C/span>: \u003Cspan class=\"hljs-subst\">{result.value}\u003C/span>&quot;\u003C/span>)\n        \u003Cspan class=\"hljs-keyword\">else\u003C/span>:\n            \u003Cspan class=\"hljs-built_in\">print\u003C/span>(\u003Cspan class=\"hljs-string\">&quot;  ✅ Structure validation passed&quot;\u003C/span>)\n        \n        \u003Cspan class=\"hljs-comment\"># Content validation (using appropriate schema)\u003C/span>\n        schema_name = \u003Cspan class=\"hljs-string\">&#x27;user_directory&#x27;\u003C/span> \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;Email&#x27;\u003C/span> \u003Cspan class=\"hljs-keyword\">in\u003C/span> table_text \u003Cspan class=\"hljs-keyword\">else\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;product_catalog&#x27;\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;Account&#x27;\u003C/span> \u003Cspan class=\"hljs-keyword\">in\u003C/span> table_text:\n            schema_name = \u003Cspan class=\"hljs-string\">&#x27;financial_report&#x27;\u003C/span>\n            \n        content_results = validator.validate_table_content(table_text, schemas[schema_name])\n        \u003Cspan class=\"hljs-built_in\">print\u003C/span>(\u003Cspan class=\"hljs-string\">&quot;\\nContent Validation:&quot;\u003C/span>)\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> content_results:\n            \u003Cspan class=\"hljs-keyword\">for\u003C/span> result \u003Cspan class=\"hljs-keyword\">in\u003C/span> content_results:\n                severity_icon = {\u003Cspan class=\"hljs-string\">&#x27;error&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;❌&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;warning&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;⚠️&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;info&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;ℹ️&#x27;\u003C/span>}\n                icon = severity_icon.get(result.severity.value, \u003Cspan class=\"hljs-string\">&#x27;•&#x27;\u003C/span>)\n                location = \u003Cspan class=\"hljs-string\">f&quot;Row \u003Cspan class=\"hljs-subst\">{result.row}\u003C/span>, Column &#x27;\u003Cspan class=\"hljs-subst\">{result.column}\u003C/span>&#x27;&quot;\u003C/span> \u003Cspan class=\"hljs-keyword\">if\u003C/span> result.row \u003Cspan class=\"hljs-keyword\">and\u003C/span> result.column \u003Cspan class=\"hljs-keyword\">else\u003C/span> \u003Cspan class=\"hljs-string\">&quot;&quot;\u003C/span>\n                \u003Cspan class=\"hljs-built_in\">print\u003C/span>(\u003Cspan class=\"hljs-string\">f&quot;  \u003Cspan class=\"hljs-subst\">{icon}\u003C/span> \u003Cspan class=\"hljs-subst\">{result.message}\u003C/span>&quot;\u003C/span>)\n                \u003Cspan class=\"hljs-keyword\">if\u003C/span> location:\n                    \u003Cspan class=\"hljs-built_in\">print\u003C/span>(\u003Cspan class=\"hljs-string\">f&quot;      \u003Cspan class=\"hljs-subst\">{location}\u003C/span>: &#x27;\u003Cspan class=\"hljs-subst\">{result.value}\u003C/span>&#x27;&quot;\u003C/span>)\n        \u003Cspan class=\"hljs-keyword\">else\u003C/span>:\n            \u003Cspan class=\"hljs-built_in\">print\u003C/span>(\u003Cspan class=\"hljs-string\">&quot;  ✅ Content validation passed&quot;\u003C/span>)\n        \n        \u003Cspan class=\"hljs-built_in\">print\u003C/span>(\u003Cspan class=\"hljs-string\">&quot;\\n&quot;\u003C/span> + \u003Cspan class=\"hljs-string\">&quot;-&quot;\u003C/span> * \u003Cspan class=\"hljs-number\">30\u003C/span>)\n\n\u003Cspan class=\"hljs-keyword\">if\u003C/span> __name__ == \u003Cspan class=\"hljs-string\">&quot;__main__&quot;\u003C/span>:\n    demonstrate_table_validation()\n\u003C/code>\u003C/pre>\u003Ch3 id=\"automated-cicd-integration\">Automated CI/CD Integration\u003C/h3>\n\u003Cp>Integrating table validation into continuous integration workflows:\u003C/p>\n\u003Cpre>\u003Ccode class=\"hljs language-python\">\u003Cspan class=\"hljs-comment\"># ci_table_validator.py - CI/CD integration for table validation\u003C/span>\n\u003Cspan class=\"hljs-keyword\">import\u003C/span> sys\n\u003Cspan class=\"hljs-keyword\">import\u003C/span> json\n\u003Cspan class=\"hljs-keyword\">import\u003C/span> argparse\n\u003Cspan class=\"hljs-keyword\">from\u003C/span> pathlib \u003Cspan class=\"hljs-keyword\">import\u003C/span> Path\n\u003Cspan class=\"hljs-keyword\">from\u003C/span> typing \u003Cspan class=\"hljs-keyword\">import\u003C/span> \u003Cspan class=\"hljs-type\">Dict\u003C/span>, \u003Cspan class=\"hljs-type\">List\u003C/span>\n\u003Cspan class=\"hljs-keyword\">import\u003C/span> subprocess\n\n\u003Cspan class=\"hljs-keyword\">class\u003C/span> \u003Cspan class=\"hljs-title class_\">CITableValidator\u003C/span>:\n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">__init__\u003C/span>(\u003Cspan class=\"hljs-params\">self, config_path: \u003Cspan class=\"hljs-type\">Optional\u003C/span>[Path] = \u003Cspan class=\"hljs-literal\">None\u003C/span>\u003C/span>):\n        self.config = self._load_config(config_path)\n        self.validator = TableValidator()\n        \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">_load_config\u003C/span>(\u003Cspan class=\"hljs-params\">self, config_path: \u003Cspan class=\"hljs-type\">Optional\u003C/span>[Path]\u003C/span>) -&gt; \u003Cspan class=\"hljs-type\">Dict\u003C/span>:\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Load validation configuration&quot;&quot;&quot;\u003C/span>\n        default_config = {\n            \u003Cspan class=\"hljs-string\">&#x27;fail_on_errors&#x27;\u003C/span>: \u003Cspan class=\"hljs-literal\">True\u003C/span>,\n            \u003Cspan class=\"hljs-string\">&#x27;fail_on_warnings&#x27;\u003C/span>: \u003Cspan class=\"hljs-literal\">False\u003C/span>,\n            \u003Cspan class=\"hljs-string\">&#x27;output_format&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;json&#x27;\u003C/span>,\n            \u003Cspan class=\"hljs-string\">&#x27;schema_directory&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;schemas&#x27;\u003C/span>,\n            \u003Cspan class=\"hljs-string\">&#x27;file_patterns&#x27;\u003C/span>: [\u003Cspan class=\"hljs-string\">&#x27;**/*.md&#x27;\u003C/span>],\n            \u003Cspan class=\"hljs-string\">&#x27;exclude_patterns&#x27;\u003C/span>: [\u003Cspan class=\"hljs-string\">&#x27;node_modules/**&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;.git/**&#x27;\u003C/span>],\n            \u003Cspan class=\"hljs-string\">&#x27;max_errors&#x27;\u003C/span>: \u003Cspan class=\"hljs-number\">0\u003C/span>,\n            \u003Cspan class=\"hljs-string\">&#x27;max_warnings&#x27;\u003C/span>: \u003Cspan class=\"hljs-number\">10\u003C/span>\n        }\n        \n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> config_path \u003Cspan class=\"hljs-keyword\">and\u003C/span> config_path.exists():\n            \u003Cspan class=\"hljs-keyword\">with\u003C/span> \u003Cspan class=\"hljs-built_in\">open\u003C/span>(config_path, \u003Cspan class=\"hljs-string\">&#x27;r&#x27;\u003C/span>, encoding=\u003Cspan class=\"hljs-string\">&#x27;utf-8&#x27;\u003C/span>) \u003Cspan class=\"hljs-keyword\">as\u003C/span> f:\n                user_config = json.load(f)\n                default_config.update(user_config)\n        \n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> default_config\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">validate_repository\u003C/span>(\u003Cspan class=\"hljs-params\">self, repo_path: Path\u003C/span>) -&gt; \u003Cspan class=\"hljs-type\">Dict\u003C/span>:\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Validate all tables in repository&quot;&quot;&quot;\u003C/span>\n        results = {\n            \u003Cspan class=\"hljs-string\">&#x27;repository&#x27;\u003C/span>: \u003Cspan class=\"hljs-built_in\">str\u003C/span>(repo_path),\n            \u003Cspan class=\"hljs-string\">&#x27;files_processed&#x27;\u003C/span>: \u003Cspan class=\"hljs-number\">0\u003C/span>,\n            \u003Cspan class=\"hljs-string\">&#x27;tables_validated&#x27;\u003C/span>: \u003Cspan class=\"hljs-number\">0\u003C/span>,\n            \u003Cspan class=\"hljs-string\">&#x27;total_errors&#x27;\u003C/span>: \u003Cspan class=\"hljs-number\">0\u003C/span>,\n            \u003Cspan class=\"hljs-string\">&#x27;total_warnings&#x27;\u003C/span>: \u003Cspan class=\"hljs-number\">0\u003C/span>,\n            \u003Cspan class=\"hljs-string\">&#x27;files_with_errors&#x27;\u003C/span>: [],\n            \u003Cspan class=\"hljs-string\">&#x27;files_with_warnings&#x27;\u003C/span>: [],\n            \u003Cspan class=\"hljs-string\">&#x27;validation_details&#x27;\u003C/span>: []\n        }\n        \n        \u003Cspan class=\"hljs-comment\"># Find all markdown files\u003C/span>\n        markdown_files = self._find_markdown_files(repo_path)\n        \n        \u003Cspan class=\"hljs-keyword\">for\u003C/span> md_file \u003Cspan class=\"hljs-keyword\">in\u003C/span> markdown_files:\n            \u003Cspan class=\"hljs-comment\"># Find schema file\u003C/span>\n            schema_file = self._find_schema_for_file(md_file)\n            \n            \u003Cspan class=\"hljs-comment\"># Validate file\u003C/span>\n            file_result = self.validator.validate_file(md_file, schema_file)\n            results[\u003Cspan class=\"hljs-string\">&#x27;files_processed&#x27;\u003C/span>] += \u003Cspan class=\"hljs-number\">1\u003C/span>\n            results[\u003Cspan class=\"hljs-string\">&#x27;tables_validated&#x27;\u003C/span>] += file_result[\u003Cspan class=\"hljs-string\">&#x27;tables_found&#x27;\u003C/span>]\n            results[\u003Cspan class=\"hljs-string\">&#x27;total_errors&#x27;\u003C/span>] += file_result[\u003Cspan class=\"hljs-string\">&#x27;summary&#x27;\u003C/span>][\u003Cspan class=\"hljs-string\">&#x27;errors&#x27;\u003C/span>]\n            results[\u003Cspan class=\"hljs-string\">&#x27;total_warnings&#x27;\u003C/span>] += file_result[\u003Cspan class=\"hljs-string\">&#x27;summary&#x27;\u003C/span>][\u003Cspan class=\"hljs-string\">&#x27;warnings&#x27;\u003C/span>]\n            \n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> file_result[\u003Cspan class=\"hljs-string\">&#x27;summary&#x27;\u003C/span>][\u003Cspan class=\"hljs-string\">&#x27;errors&#x27;\u003C/span>] &gt; \u003Cspan class=\"hljs-number\">0\u003C/span>:\n                results[\u003Cspan class=\"hljs-string\">&#x27;files_with_errors&#x27;\u003C/span>].append(\u003Cspan class=\"hljs-built_in\">str\u003C/span>(md_file))\n            \n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> file_result[\u003Cspan class=\"hljs-string\">&#x27;summary&#x27;\u003C/span>][\u003Cspan class=\"hljs-string\">&#x27;warnings&#x27;\u003C/span>] &gt; \u003Cspan class=\"hljs-number\">0\u003C/span>:\n                results[\u003Cspan class=\"hljs-string\">&#x27;files_with_warnings&#x27;\u003C/span>].append(\u003Cspan class=\"hljs-built_in\">str\u003C/span>(md_file))\n            \n            results[\u003Cspan class=\"hljs-string\">&#x27;validation_details&#x27;\u003C/span>].append(file_result)\n        \n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> results\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">_find_markdown_files\u003C/span>(\u003Cspan class=\"hljs-params\">self, repo_path: Path\u003C/span>) -&gt; \u003Cspan class=\"hljs-type\">List\u003C/span>[Path]:\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Find all markdown files to validate&quot;&quot;&quot;\u003C/span>\n        markdown_files = []\n        \n        \u003Cspan class=\"hljs-keyword\">for\u003C/span> pattern \u003Cspan class=\"hljs-keyword\">in\u003C/span> self.config[\u003Cspan class=\"hljs-string\">&#x27;file_patterns&#x27;\u003C/span>]:\n            files = repo_path.glob(pattern)\n            \u003Cspan class=\"hljs-keyword\">for\u003C/span> file_path \u003Cspan class=\"hljs-keyword\">in\u003C/span> files:\n                \u003Cspan class=\"hljs-comment\"># Check exclude patterns\u003C/span>\n                excluded = \u003Cspan class=\"hljs-literal\">False\u003C/span>\n                \u003Cspan class=\"hljs-keyword\">for\u003C/span> exclude_pattern \u003Cspan class=\"hljs-keyword\">in\u003C/span> self.config[\u003Cspan class=\"hljs-string\">&#x27;exclude_patterns&#x27;\u003C/span>]:\n                    \u003Cspan class=\"hljs-keyword\">if\u003C/span> file_path.\u003Cspan class=\"hljs-keyword\">match\u003C/span>(exclude_pattern):\n                        excluded = \u003Cspan class=\"hljs-literal\">True\u003C/span>\n                        \u003Cspan class=\"hljs-keyword\">break\u003C/span>\n                \n                \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-keyword\">not\u003C/span> excluded:\n                    markdown_files.append(file_path)\n        \n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> markdown_files\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">_find_schema_for_file\u003C/span>(\u003Cspan class=\"hljs-params\">self, md_file: Path\u003C/span>) -&gt; \u003Cspan class=\"hljs-type\">Optional\u003C/span>[Path]:\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Find appropriate schema file for markdown file&quot;&quot;&quot;\u003C/span>\n        schema_dir = Path(self.config[\u003Cspan class=\"hljs-string\">&#x27;schema_directory&#x27;\u003C/span>])\n        \n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-keyword\">not\u003C/span> schema_dir.exists():\n            \u003Cspan class=\"hljs-keyword\">return\u003C/span> \u003Cspan class=\"hljs-literal\">None\u003C/span>\n        \n        \u003Cspan class=\"hljs-comment\"># Look for specific schema file\u003C/span>\n        schema_name = md_file.stem + \u003Cspan class=\"hljs-string\">&#x27;.json&#x27;\u003C/span>\n        specific_schema = schema_dir / schema_name\n        \n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> specific_schema.exists():\n            \u003Cspan class=\"hljs-keyword\">return\u003C/span> specific_schema\n        \n        \u003Cspan class=\"hljs-comment\"># Look for default schema\u003C/span>\n        default_schema = schema_dir / \u003Cspan class=\"hljs-string\">&#x27;default.json&#x27;\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> default_schema.exists():\n            \u003Cspan class=\"hljs-keyword\">return\u003C/span> default_schema\n        \n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> \u003Cspan class=\"hljs-literal\">None\u003C/span>\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">generate_ci_report\u003C/span>(\u003Cspan class=\"hljs-params\">self, results: \u003Cspan class=\"hljs-type\">Dict\u003C/span>\u003C/span>) -&gt; \u003Cspan class=\"hljs-built_in\">str\u003C/span>:\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Generate CI-friendly report&quot;&quot;&quot;\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> self.config[\u003Cspan class=\"hljs-string\">&#x27;output_format&#x27;\u003C/span>] == \u003Cspan class=\"hljs-string\">&#x27;json&#x27;\u003C/span>:\n            \u003Cspan class=\"hljs-keyword\">return\u003C/span> json.dumps(results, indent=\u003Cspan class=\"hljs-number\">2\u003C/span>)\n        \n        \u003Cspan class=\"hljs-comment\"># Generate text report\u003C/span>\n        report = []\n        report.append(\u003Cspan class=\"hljs-string\">&quot;# Table Validation CI Report&quot;\u003C/span>)\n        report.append(\u003Cspan class=\"hljs-string\">f&quot;Repository: \u003Cspan class=\"hljs-subst\">{results[\u003Cspan class=\"hljs-string\">&#x27;repository&#x27;\u003C/span>]}\u003C/span>&quot;\u003C/span>)\n        report.append(\u003Cspan class=\"hljs-string\">f&quot;Files Processed: \u003Cspan class=\"hljs-subst\">{results[\u003Cspan class=\"hljs-string\">&#x27;files_processed&#x27;\u003C/span>]}\u003C/span>&quot;\u003C/span>)\n        report.append(\u003Cspan class=\"hljs-string\">f&quot;Tables Validated: \u003Cspan class=\"hljs-subst\">{results[\u003Cspan class=\"hljs-string\">&#x27;tables_validated&#x27;\u003C/span>]}\u003C/span>&quot;\u003C/span>)\n        report.append(\u003Cspan class=\"hljs-string\">f&quot;Total Errors: \u003Cspan class=\"hljs-subst\">{results[\u003Cspan class=\"hljs-string\">&#x27;total_errors&#x27;\u003C/span>]}\u003C/span>&quot;\u003C/span>)\n        report.append(\u003Cspan class=\"hljs-string\">f&quot;Total Warnings: \u003Cspan class=\"hljs-subst\">{results[\u003Cspan class=\"hljs-string\">&#x27;total_warnings&#x27;\u003C/span>]}\u003C/span>&quot;\u003C/span>)\n        report.append(\u003Cspan class=\"hljs-string\">&quot;&quot;\u003C/span>)\n        \n        \u003Cspan class=\"hljs-comment\"># Overall status\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> results[\u003Cspan class=\"hljs-string\">&#x27;total_errors&#x27;\u003C/span>] == \u003Cspan class=\"hljs-number\">0\u003C/span> \u003Cspan class=\"hljs-keyword\">and\u003C/span> results[\u003Cspan class=\"hljs-string\">&#x27;total_warnings&#x27;\u003C/span>] == \u003Cspan class=\"hljs-number\">0\u003C/span>:\n            report.append(\u003Cspan class=\"hljs-string\">&quot;✅ **ALL VALIDATIONS PASSED**&quot;\u003C/span>)\n        \u003Cspan class=\"hljs-keyword\">elif\u003C/span> results[\u003Cspan class=\"hljs-string\">&#x27;total_errors&#x27;\u003C/span>] == \u003Cspan class=\"hljs-number\">0\u003C/span>:\n            report.append(\u003Cspan class=\"hljs-string\">f&quot;⚠️ **VALIDATION PASSED WITH \u003Cspan class=\"hljs-subst\">{results[\u003Cspan class=\"hljs-string\">&#x27;total_warnings&#x27;\u003C/span>]}\u003C/span> WARNINGS**&quot;\u003C/span>)\n        \u003Cspan class=\"hljs-keyword\">else\u003C/span>:\n            report.append(\u003Cspan class=\"hljs-string\">f&quot;❌ **VALIDATION FAILED WITH \u003Cspan class=\"hljs-subst\">{results[\u003Cspan class=\"hljs-string\">&#x27;total_errors&#x27;\u003C/span>]}\u003C/span> ERRORS**&quot;\u003C/span>)\n        \n        report.append(\u003Cspan class=\"hljs-string\">&quot;&quot;\u003C/span>)\n        \n        \u003Cspan class=\"hljs-comment\"># Files with issues\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> results[\u003Cspan class=\"hljs-string\">&#x27;files_with_errors&#x27;\u003C/span>]:\n            report.append(\u003Cspan class=\"hljs-string\">&quot;## Files with Errors:&quot;\u003C/span>)\n            \u003Cspan class=\"hljs-keyword\">for\u003C/span> file_path \u003Cspan class=\"hljs-keyword\">in\u003C/span> results[\u003Cspan class=\"hljs-string\">&#x27;files_with_errors&#x27;\u003C/span>]:\n                report.append(\u003Cspan class=\"hljs-string\">f&quot;- \u003Cspan class=\"hljs-subst\">{file_path}\u003C/span>&quot;\u003C/span>)\n            report.append(\u003Cspan class=\"hljs-string\">&quot;&quot;\u003C/span>)\n        \n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> results[\u003Cspan class=\"hljs-string\">&#x27;files_with_warnings&#x27;\u003C/span>]:\n            report.append(\u003Cspan class=\"hljs-string\">&quot;## Files with Warnings:&quot;\u003C/span>)\n            \u003Cspan class=\"hljs-keyword\">for\u003C/span> file_path \u003Cspan class=\"hljs-keyword\">in\u003C/span> results[\u003Cspan class=\"hljs-string\">&#x27;files_with_warnings&#x27;\u003C/span>]:\n                report.append(\u003Cspan class=\"hljs-string\">f&quot;- \u003Cspan class=\"hljs-subst\">{file_path}\u003C/span>&quot;\u003C/span>)\n            report.append(\u003Cspan class=\"hljs-string\">&quot;&quot;\u003C/span>)\n        \n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;\\n&#x27;\u003C/span>.join(report)\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">should_fail_build\u003C/span>(\u003Cspan class=\"hljs-params\">self, results: \u003Cspan class=\"hljs-type\">Dict\u003C/span>\u003C/span>) -&gt; \u003Cspan class=\"hljs-built_in\">bool\u003C/span>:\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Determine if CI build should fail based on results&quot;&quot;&quot;\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> self.config[\u003Cspan class=\"hljs-string\">&#x27;fail_on_errors&#x27;\u003C/span>] \u003Cspan class=\"hljs-keyword\">and\u003C/span> results[\u003Cspan class=\"hljs-string\">&#x27;total_errors&#x27;\u003C/span>] &gt; self.config[\u003Cspan class=\"hljs-string\">&#x27;max_errors&#x27;\u003C/span>]:\n            \u003Cspan class=\"hljs-keyword\">return\u003C/span> \u003Cspan class=\"hljs-literal\">True\u003C/span>\n        \n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> self.config[\u003Cspan class=\"hljs-string\">&#x27;fail_on_warnings&#x27;\u003C/span>] \u003Cspan class=\"hljs-keyword\">and\u003C/span> results[\u003Cspan class=\"hljs-string\">&#x27;total_warnings&#x27;\u003C/span>] &gt; self.config[\u003Cspan class=\"hljs-string\">&#x27;max_warnings&#x27;\u003C/span>]:\n            \u003Cspan class=\"hljs-keyword\">return\u003C/span> \u003Cspan class=\"hljs-literal\">True\u003C/span>\n        \n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> \u003Cspan class=\"hljs-literal\">False\u003C/span>\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">run_ci_validation\u003C/span>(\u003Cspan class=\"hljs-params\">self, repo_path: \u003Cspan class=\"hljs-built_in\">str\u003C/span>\u003C/span>) -&gt; \u003Cspan class=\"hljs-built_in\">int\u003C/span>:\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Run validation in CI environment&quot;&quot;&quot;\u003C/span>\n        repo = Path(repo_path)\n        \n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-keyword\">not\u003C/span> repo.exists():\n            \u003Cspan class=\"hljs-built_in\">print\u003C/span>(\u003Cspan class=\"hljs-string\">f&quot;Error: Repository path \u003Cspan class=\"hljs-subst\">{repo_path}\u003C/span> does not exist&quot;\u003C/span>)\n            \u003Cspan class=\"hljs-keyword\">return\u003C/span> \u003Cspan class=\"hljs-number\">1\u003C/span>\n        \n        \u003Cspan class=\"hljs-comment\"># Run validation\u003C/span>\n        results = self.validate_repository(repo)\n        \n        \u003Cspan class=\"hljs-comment\"># Generate and output report\u003C/span>\n        report = self.generate_ci_report(results)\n        \u003Cspan class=\"hljs-built_in\">print\u003C/span>(report)\n        \n        \u003Cspan class=\"hljs-comment\"># Determine exit code\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> self.should_fail_build(results):\n            \u003Cspan class=\"hljs-built_in\">print\u003C/span>(\u003Cspan class=\"hljs-string\">f&quot;\\n❌ Build failed due to validation errors/warnings&quot;\u003C/span>)\n            \u003Cspan class=\"hljs-keyword\">return\u003C/span> \u003Cspan class=\"hljs-number\">1\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">else\u003C/span>:\n            \u003Cspan class=\"hljs-built_in\">print\u003C/span>(\u003Cspan class=\"hljs-string\">f&quot;\\n✅ Build passed validation&quot;\u003C/span>)\n            \u003Cspan class=\"hljs-keyword\">return\u003C/span> \u003Cspan class=\"hljs-number\">0\u003C/span>\n\n\u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">main\u003C/span>():\n    parser = argparse.ArgumentParser(description=\u003Cspan class=\"hljs-string\">&#x27;CI Table Validation Tool&#x27;\u003C/span>)\n    parser.add_argument(\u003Cspan class=\"hljs-string\">&#x27;repository&#x27;\u003C/span>, \u003Cspan class=\"hljs-built_in\">help\u003C/span>=\u003Cspan class=\"hljs-string\">&#x27;Path to repository to validate&#x27;\u003C/span>)\n    parser.add_argument(\u003Cspan class=\"hljs-string\">&#x27;--config&#x27;\u003C/span>, \u003Cspan class=\"hljs-built_in\">help\u003C/span>=\u003Cspan class=\"hljs-string\">&#x27;Path to configuration file&#x27;\u003C/span>)\n    parser.add_argument(\u003Cspan class=\"hljs-string\">&#x27;--output-format&#x27;\u003C/span>, choices=[\u003Cspan class=\"hljs-string\">&#x27;json&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;text&#x27;\u003C/span>], default=\u003Cspan class=\"hljs-string\">&#x27;text&#x27;\u003C/span>,\n                       \u003Cspan class=\"hljs-built_in\">help\u003C/span>=\u003Cspan class=\"hljs-string\">&#x27;Output format for validation results&#x27;\u003C/span>)\n    \n    args = parser.parse_args()\n    \n    \u003Cspan class=\"hljs-comment\"># Create validator with configuration\u003C/span>\n    config_path = Path(args.config) \u003Cspan class=\"hljs-keyword\">if\u003C/span> args.config \u003Cspan class=\"hljs-keyword\">else\u003C/span> \u003Cspan class=\"hljs-literal\">None\u003C/span>\n    validator = CITableValidator(config_path)\n    \n    \u003Cspan class=\"hljs-comment\"># Override output format if specified\u003C/span>\n    \u003Cspan class=\"hljs-keyword\">if\u003C/span> args.output_format:\n        validator.config[\u003Cspan class=\"hljs-string\">&#x27;output_format&#x27;\u003C/span>] = args.output_format\n    \n    \u003Cspan class=\"hljs-comment\"># Run validation\u003C/span>\n    exit_code = validator.run_ci_validation(args.repository)\n    sys.exit(exit_code)\n\n\u003Cspan class=\"hljs-keyword\">if\u003C/span> __name__ == \u003Cspan class=\"hljs-string\">&quot;__main__&quot;\u003C/span>:\n    main()\n\u003C/code>\u003C/pre>\u003Ch2 id=\"platform-integration-workflows\">Platform Integration Workflows\u003C/h2>\n\u003Ch3 id=\"github-actions-integration\">GitHub Actions Integration\u003C/h3>\n\u003Cp>Complete GitHub Actions workflow for automated table validation:\u003C/p>\n\u003Cpre>\u003Ccode class=\"hljs language-yaml\">\u003Cspan class=\"hljs-comment\"># .github/workflows/table-validation.yml\u003C/span>\n\u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Table\u003C/span> \u003Cspan class=\"hljs-string\">Validation\u003C/span>\n\n\u003Cspan class=\"hljs-attr\">on:\u003C/span>\n  \u003Cspan class=\"hljs-attr\">push:\u003C/span>\n    \u003Cspan class=\"hljs-attr\">branches:\u003C/span> [ \u003Cspan class=\"hljs-string\">main\u003C/span>, \u003Cspan class=\"hljs-string\">develop\u003C/span> ]\n    \u003Cspan class=\"hljs-attr\">paths:\u003C/span> [ \u003Cspan class=\"hljs-string\">&#x27;**.md&#x27;\u003C/span> ]\n  \u003Cspan class=\"hljs-attr\">pull_request:\u003C/span>\n    \u003Cspan class=\"hljs-attr\">branches:\u003C/span> [ \u003Cspan class=\"hljs-string\">main\u003C/span> ]\n    \u003Cspan class=\"hljs-attr\">paths:\u003C/span> [ \u003Cspan class=\"hljs-string\">&#x27;**.md&#x27;\u003C/span> ]\n\n\u003Cspan class=\"hljs-attr\">jobs:\u003C/span>\n  \u003Cspan class=\"hljs-attr\">validate-tables:\u003C/span>\n    \u003Cspan class=\"hljs-attr\">runs-on:\u003C/span> \u003Cspan class=\"hljs-string\">ubuntu-latest\u003C/span>\n    \n    \u003Cspan class=\"hljs-attr\">steps:\u003C/span>\n    \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Checkout\u003C/span> \u003Cspan class=\"hljs-string\">code\u003C/span>\n      \u003Cspan class=\"hljs-attr\">uses:\u003C/span> \u003Cspan class=\"hljs-string\">actions/checkout@v3\u003C/span>\n    \n    \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Set\u003C/span> \u003Cspan class=\"hljs-string\">up\u003C/span> \u003Cspan class=\"hljs-string\">Python\u003C/span>\n      \u003Cspan class=\"hljs-attr\">uses:\u003C/span> \u003Cspan class=\"hljs-string\">actions/setup-python@v4\u003C/span>\n      \u003Cspan class=\"hljs-attr\">with:\u003C/span>\n        \u003Cspan class=\"hljs-attr\">python-version:\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;3.9&#x27;\u003C/span>\n    \n    \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Install\u003C/span> \u003Cspan class=\"hljs-string\">dependencies\u003C/span>\n      \u003Cspan class=\"hljs-attr\">run:\u003C/span> \u003Cspan class=\"hljs-string\">|\n        pip install validators pandas python-frontmatter\n\u003C/span>        \n    \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Create\u003C/span> \u003Cspan class=\"hljs-string\">validation\u003C/span> \u003Cspan class=\"hljs-string\">schemas\u003C/span>\n      \u003Cspan class=\"hljs-attr\">run:\u003C/span> \u003Cspan class=\"hljs-string\">|\n        mkdir -p schemas\n        cat &gt; schemas/default.json &lt;&lt; EOF\n        {\n          &quot;required_columns&quot;: [],\n          &quot;columns&quot;: {\n            &quot;Name&quot;: {\n              &quot;type&quot;: &quot;alpha_only&quot;,\n              &quot;required&quot;: false,\n              &quot;max_length&quot;: 100\n            },\n            &quot;Email&quot;: {\n              &quot;type&quot;: &quot;email&quot;,\n              &quot;required&quot;: false\n            },\n            &quot;Date&quot;: {\n              &quot;type&quot;: &quot;iso_date&quot;,\n              &quot;required&quot;: false\n            },\n            &quot;Status&quot;: {\n              &quot;allowed_values&quot;: [&quot;Active&quot;, &quot;Inactive&quot;, &quot;Pending&quot;],\n              &quot;required&quot;: false\n            }\n          }\n        }\n        EOF\n\u003C/span>    \n    \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Run\u003C/span> \u003Cspan class=\"hljs-string\">table\u003C/span> \u003Cspan class=\"hljs-string\">validation\u003C/span>\n      \u003Cspan class=\"hljs-attr\">run:\u003C/span> \u003Cspan class=\"hljs-string\">|\n        python ci_table_validator.py . --config .github/table-validation.json\n\u003C/span>      \n    \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Upload\u003C/span> \u003Cspan class=\"hljs-string\">validation\u003C/span> \u003Cspan class=\"hljs-string\">report\u003C/span>\n      \u003Cspan class=\"hljs-attr\">if:\u003C/span> \u003Cspan class=\"hljs-string\">always()\u003C/span>\n      \u003Cspan class=\"hljs-attr\">uses:\u003C/span> \u003Cspan class=\"hljs-string\">actions/upload-artifact@v3\u003C/span>\n      \u003Cspan class=\"hljs-attr\">with:\u003C/span>\n        \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">table-validation-report\u003C/span>\n        \u003Cspan class=\"hljs-attr\">path:\u003C/span> \u003Cspan class=\"hljs-string\">validation-report.json\u003C/span>\n    \n    \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Comment\u003C/span> \u003Cspan class=\"hljs-string\">PR\u003C/span> \u003Cspan class=\"hljs-string\">with\u003C/span> \u003Cspan class=\"hljs-string\">results\u003C/span>\n      \u003Cspan class=\"hljs-attr\">if:\u003C/span> \u003Cspan class=\"hljs-string\">github.event_name\u003C/span> \u003Cspan class=\"hljs-string\">==\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;pull_request&#x27;\u003C/span>\n      \u003Cspan class=\"hljs-attr\">uses:\u003C/span> \u003Cspan class=\"hljs-string\">actions/github-script@v6\u003C/span>\n      \u003Cspan class=\"hljs-attr\">with:\u003C/span>\n        \u003Cspan class=\"hljs-attr\">script:\u003C/span> \u003Cspan class=\"hljs-string\">|\n          const fs = require(&#x27;fs&#x27;);\n\u003C/span>          \n          \u003Cspan class=\"hljs-string\">try\u003C/span> {\n            \u003Cspan class=\"hljs-string\">const\u003C/span> \u003Cspan class=\"hljs-string\">report\u003C/span> \u003Cspan class=\"hljs-string\">=\u003C/span> \u003Cspan class=\"hljs-string\">fs.readFileSync(&#x27;validation-report.json&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;utf8&#x27;\u003C/span>\u003Cspan class=\"hljs-string\">);\u003C/span>\n            \u003Cspan class=\"hljs-string\">const\u003C/span> \u003Cspan class=\"hljs-string\">results\u003C/span> \u003Cspan class=\"hljs-string\">=\u003C/span> \u003Cspan class=\"hljs-string\">JSON.parse(report);\u003C/span>\n            \n            \u003Cspan class=\"hljs-string\">let\u003C/span> \u003Cspan class=\"hljs-string\">comment\u003C/span> \u003Cspan class=\"hljs-string\">=\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;## Table Validation Results\\\\n\\\\n&#x27;\u003C/span>\u003Cspan class=\"hljs-string\">;\u003C/span>\n            \n            \u003Cspan class=\"hljs-string\">if\u003C/span> \u003Cspan class=\"hljs-string\">(results.total_errors\u003C/span> \u003Cspan class=\"hljs-string\">===\u003C/span> \u003Cspan class=\"hljs-number\">0\u003C/span> \u003Cspan class=\"hljs-string\">&amp;&amp;\u003C/span> \u003Cspan class=\"hljs-string\">results.total_warnings\u003C/span> \u003Cspan class=\"hljs-string\">===\u003C/span> \u003Cspan class=\"hljs-number\">0\u003C/span>\u003Cspan class=\"hljs-string\">)\u003C/span> {\n              \u003Cspan class=\"hljs-string\">comment\u003C/span> \u003Cspan class=\"hljs-string\">+=\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;✅ **All table validations passed!**\\\\n\\\\n&#x27;\u003C/span>\u003Cspan class=\"hljs-string\">;\u003C/span>\n            } \u003Cspan class=\"hljs-string\">else\u003C/span> {\n              \u003Cspan class=\"hljs-string\">comment\u003C/span> \u003Cspan class=\"hljs-string\">+=\u003C/span> \u003Cspan class=\"hljs-string\">`❌\u003C/span> \u003Cspan class=\"hljs-string\">Found\u003C/span> \u003Cspan class=\"hljs-string\">$\u003C/span>{\u003Cspan class=\"hljs-string\">results.total_errors\u003C/span>} \u003Cspan class=\"hljs-string\">errors\u003C/span> \u003Cspan class=\"hljs-string\">and\u003C/span> \u003Cspan class=\"hljs-string\">$\u003C/span>{\u003Cspan class=\"hljs-string\">results.total_warnings\u003C/span>} \u003Cspan class=\"hljs-string\">warnings\\\\n\\\\n`;\u003C/span>\n              \n              \u003Cspan class=\"hljs-string\">if\u003C/span> \u003Cspan class=\"hljs-string\">(results.files_with_errors.length\u003C/span> \u003Cspan class=\"hljs-string\">&gt;\u003C/span> \u003Cspan class=\"hljs-number\">0\u003C/span>\u003Cspan class=\"hljs-string\">)\u003C/span> {\n                \u003Cspan class=\"hljs-string\">comment\u003C/span> \u003Cspan class=\"hljs-string\">+=\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;### Files with Errors:\\\\n&#x27;\u003C/span>\u003Cspan class=\"hljs-string\">;\u003C/span>\n                \u003Cspan class=\"hljs-string\">results.files_with_errors.forEach(file\u003C/span> \u003Cspan class=\"hljs-string\">=&gt;\u003C/span> {\n                  \u003Cspan class=\"hljs-string\">comment\u003C/span> \u003Cspan class=\"hljs-string\">+=\u003C/span> \u003Cspan class=\"hljs-string\">`-\u003C/span> \u003Cspan class=\"hljs-string\">$\u003C/span>{\u003Cspan class=\"hljs-string\">file\u003C/span>}\u003Cspan class=\"hljs-string\">\\\\n`;\u003C/span>\n                }\u003Cspan class=\"hljs-string\">);\u003C/span>\n                \u003Cspan class=\"hljs-string\">comment\u003C/span> \u003Cspan class=\"hljs-string\">+=\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;\\\\n&#x27;\u003C/span>\u003Cspan class=\"hljs-string\">;\u003C/span>\n              }\n              \n              \u003Cspan class=\"hljs-string\">if\u003C/span> \u003Cspan class=\"hljs-string\">(results.files_with_warnings.length\u003C/span> \u003Cspan class=\"hljs-string\">&gt;\u003C/span> \u003Cspan class=\"hljs-number\">0\u003C/span>\u003Cspan class=\"hljs-string\">)\u003C/span> {\n                \u003Cspan class=\"hljs-string\">comment\u003C/span> \u003Cspan class=\"hljs-string\">+=\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;### Files with Warnings:\\\\n&#x27;\u003C/span>\u003Cspan class=\"hljs-string\">;\u003C/span>\n                \u003Cspan class=\"hljs-string\">results.files_with_warnings.forEach(file\u003C/span> \u003Cspan class=\"hljs-string\">=&gt;\u003C/span> {\n                  \u003Cspan class=\"hljs-string\">comment\u003C/span> \u003Cspan class=\"hljs-string\">+=\u003C/span> \u003Cspan class=\"hljs-string\">`-\u003C/span> \u003Cspan class=\"hljs-string\">$\u003C/span>{\u003Cspan class=\"hljs-string\">file\u003C/span>}\u003Cspan class=\"hljs-string\">\\\\n`;\u003C/span>\n                }\u003Cspan class=\"hljs-string\">);\u003C/span>\n              }\n            }\n            \n            \u003Cspan class=\"hljs-string\">comment\u003C/span> \u003Cspan class=\"hljs-string\">+=\u003C/span> \u003Cspan class=\"hljs-string\">`\\\\n**Summary**:\u003C/span> \u003Cspan class=\"hljs-string\">$\u003C/span>{\u003Cspan class=\"hljs-string\">results.files_processed\u003C/span>} \u003Cspan class=\"hljs-string\">files\u003C/span> \u003Cspan class=\"hljs-string\">processed\u003C/span>, \u003Cspan class=\"hljs-string\">$\u003C/span>{\u003Cspan class=\"hljs-string\">results.tables_validated\u003C/span>} \u003Cspan class=\"hljs-string\">tables\u003C/span> \u003Cspan class=\"hljs-string\">validated`;\u003C/span>\n            \n            \u003Cspan class=\"hljs-string\">github.rest.issues.createComment(\u003C/span>{\n              \u003Cspan class=\"hljs-attr\">issue_number:\u003C/span> \u003Cspan class=\"hljs-string\">context.issue.number\u003C/span>,\n              \u003Cspan class=\"hljs-attr\">owner:\u003C/span> \u003Cspan class=\"hljs-string\">context.repo.owner\u003C/span>,\n              \u003Cspan class=\"hljs-attr\">repo:\u003C/span> \u003Cspan class=\"hljs-string\">context.repo.repo\u003C/span>,\n              \u003Cspan class=\"hljs-attr\">body:\u003C/span> \u003Cspan class=\"hljs-string\">comment\u003C/span>\n            }\u003Cspan class=\"hljs-string\">);\u003C/span>\n          } \u003Cspan class=\"hljs-string\">catch\u003C/span> \u003Cspan class=\"hljs-string\">(error)\u003C/span> {\n            \u003Cspan class=\"hljs-string\">console.log(&#x27;Could\u003C/span> \u003Cspan class=\"hljs-string\">not\u003C/span> \u003Cspan class=\"hljs-string\">read\u003C/span> \u003Cspan class=\"hljs-string\">validation\u003C/span> \u003Cspan class=\"hljs-string\">report:&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">error);\u003C/span>\n          }\n\n  \u003Cspan class=\"hljs-comment\"># Optional: Generate and publish validation badge\u003C/span>\n  \u003Cspan class=\"hljs-attr\">update-badge:\u003C/span>\n    \u003Cspan class=\"hljs-attr\">needs:\u003C/span> \u003Cspan class=\"hljs-string\">validate-tables\u003C/span>\n    \u003Cspan class=\"hljs-attr\">runs-on:\u003C/span> \u003Cspan class=\"hljs-string\">ubuntu-latest\u003C/span>\n    \u003Cspan class=\"hljs-attr\">if:\u003C/span> \u003Cspan class=\"hljs-string\">github.ref\u003C/span> \u003Cspan class=\"hljs-string\">==\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;refs/heads/main&#x27;\u003C/span>\n    \n    \u003Cspan class=\"hljs-attr\">steps:\u003C/span>\n    \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Create\u003C/span> \u003Cspan class=\"hljs-string\">validation\u003C/span> \u003Cspan class=\"hljs-string\">badge\u003C/span>\n      \u003Cspan class=\"hljs-attr\">uses:\u003C/span> \u003Cspan class=\"hljs-string\">schneegans/dynamic-badges-action@v1.4.0\u003C/span>\n      \u003Cspan class=\"hljs-attr\">with:\u003C/span>\n        \u003Cspan class=\"hljs-attr\">auth:\u003C/span> \u003Cspan class=\"hljs-string\">${{\u003C/span> \u003Cspan class=\"hljs-string\">secrets.GIST_SECRET\u003C/span> \u003Cspan class=\"hljs-string\">}}\u003C/span>\n        \u003Cspan class=\"hljs-attr\">gistID:\u003C/span> \u003Cspan class=\"hljs-string\">your-gist-id-here\u003C/span>\n        \u003Cspan class=\"hljs-attr\">filename:\u003C/span> \u003Cspan class=\"hljs-string\">table-validation-badge.json\u003C/span>\n        \u003Cspan class=\"hljs-attr\">label:\u003C/span> \u003Cspan class=\"hljs-string\">Table\u003C/span> \u003Cspan class=\"hljs-string\">Validation\u003C/span>\n        \u003Cspan class=\"hljs-attr\">message:\u003C/span> \u003Cspan class=\"hljs-string\">Passing\u003C/span>\n        \u003Cspan class=\"hljs-attr\">color:\u003C/span> \u003Cspan class=\"hljs-string\">green\u003C/span>\n\u003C/code>\u003C/pre>\u003Ch3 id=\"pre-commit-hook-integration\">Pre-commit Hook Integration\u003C/h3>\n\u003Cp>Git pre-commit hook for table validation:\u003C/p>\n\u003Cpre>\u003Ccode class=\"hljs language-bash\">\u003Cspan class=\"hljs-meta\">#!/bin/bash\u003C/span>\n\u003Cspan class=\"hljs-comment\"># .git/hooks/pre-commit - Table validation pre-commit hook\u003C/span>\n\n\u003Cspan class=\"hljs-built_in\">echo\u003C/span> \u003Cspan class=\"hljs-string\">&quot;Running table validation...&quot;\u003C/span>\n\n\u003Cspan class=\"hljs-comment\"># Check if validation script exists\u003C/span>\n\u003Cspan class=\"hljs-keyword\">if\u003C/span> [ ! -f \u003Cspan class=\"hljs-string\">&quot;scripts/validate_tables.py&quot;\u003C/span> ]; \u003Cspan class=\"hljs-keyword\">then\u003C/span>\n    \u003Cspan class=\"hljs-built_in\">echo\u003C/span> \u003Cspan class=\"hljs-string\">&quot;Warning: Table validation script not found, skipping validation&quot;\u003C/span>\n    \u003Cspan class=\"hljs-built_in\">exit\u003C/span> 0\n\u003Cspan class=\"hljs-keyword\">fi\u003C/span>\n\n\u003Cspan class=\"hljs-comment\"># Get list of staged markdown files\u003C/span>\nstaged_files=$(git diff --cached --name-only --diff-filter=ACM | grep \u003Cspan class=\"hljs-string\">&#x27;\\.md$&#x27;\u003C/span>)\n\n\u003Cspan class=\"hljs-keyword\">if\u003C/span> [ -z \u003Cspan class=\"hljs-string\">&quot;\u003Cspan class=\"hljs-variable\">$staged_files\u003C/span>&quot;\u003C/span> ]; \u003Cspan class=\"hljs-keyword\">then\u003C/span>\n    \u003Cspan class=\"hljs-built_in\">echo\u003C/span> \u003Cspan class=\"hljs-string\">&quot;No markdown files to validate&quot;\u003C/span>\n    \u003Cspan class=\"hljs-built_in\">exit\u003C/span> 0\n\u003Cspan class=\"hljs-keyword\">fi\u003C/span>\n\n\u003Cspan class=\"hljs-comment\"># Run validation on staged files\u003C/span>\nvalidation_failed=\u003Cspan class=\"hljs-literal\">false\u003C/span>\n\n\u003Cspan class=\"hljs-keyword\">for\u003C/span> file \u003Cspan class=\"hljs-keyword\">in\u003C/span> \u003Cspan class=\"hljs-variable\">$staged_files\u003C/span>; \u003Cspan class=\"hljs-keyword\">do\u003C/span>\n    \u003Cspan class=\"hljs-built_in\">echo\u003C/span> \u003Cspan class=\"hljs-string\">&quot;Validating tables in: \u003Cspan class=\"hljs-variable\">$file\u003C/span>&quot;\u003C/span>\n    \n    \u003Cspan class=\"hljs-comment\"># Run table validation\u003C/span>\n    python scripts/validate_tables.py \u003Cspan class=\"hljs-string\">&quot;\u003Cspan class=\"hljs-variable\">$file\u003C/span>&quot;\u003C/span> --strict\n    \n    \u003Cspan class=\"hljs-keyword\">if\u003C/span> [ $? -ne 0 ]; \u003Cspan class=\"hljs-keyword\">then\u003C/span>\n        \u003Cspan class=\"hljs-built_in\">echo\u003C/span> \u003Cspan class=\"hljs-string\">&quot;❌ Table validation failed for: \u003Cspan class=\"hljs-variable\">$file\u003C/span>&quot;\u003C/span>\n        validation_failed=\u003Cspan class=\"hljs-literal\">true\u003C/span>\n    \u003Cspan class=\"hljs-keyword\">else\u003C/span>\n        \u003Cspan class=\"hljs-built_in\">echo\u003C/span> \u003Cspan class=\"hljs-string\">&quot;✅ Table validation passed for: \u003Cspan class=\"hljs-variable\">$file\u003C/span>&quot;\u003C/span>\n    \u003Cspan class=\"hljs-keyword\">fi\u003C/span>\n\u003Cspan class=\"hljs-keyword\">done\u003C/span>\n\n\u003Cspan class=\"hljs-keyword\">if\u003C/span> [ \u003Cspan class=\"hljs-string\">&quot;\u003Cspan class=\"hljs-variable\">$validation_failed\u003C/span>&quot;\u003C/span> = \u003Cspan class=\"hljs-literal\">true\u003C/span> ]; \u003Cspan class=\"hljs-keyword\">then\u003C/span>\n    \u003Cspan class=\"hljs-built_in\">echo\u003C/span> \u003Cspan class=\"hljs-string\">&quot;&quot;\u003C/span>\n    \u003Cspan class=\"hljs-built_in\">echo\u003C/span> \u003Cspan class=\"hljs-string\">&quot;❌ Commit rejected: Table validation failed&quot;\u003C/span>\n    \u003Cspan class=\"hljs-built_in\">echo\u003C/span> \u003Cspan class=\"hljs-string\">&quot;Please fix the table validation errors and try again&quot;\u003C/span>\n    \u003Cspan class=\"hljs-built_in\">echo\u003C/span> \u003Cspan class=\"hljs-string\">&quot;&quot;\u003C/span>\n    \u003Cspan class=\"hljs-built_in\">echo\u003C/span> \u003Cspan class=\"hljs-string\">&quot;To skip validation (not recommended), use: git commit --no-verify&quot;\u003C/span>\n    \u003Cspan class=\"hljs-built_in\">exit\u003C/span> 1\n\u003Cspan class=\"hljs-keyword\">fi\u003C/span>\n\n\u003Cspan class=\"hljs-built_in\">echo\u003C/span> \u003Cspan class=\"hljs-string\">&quot;✅ All table validations passed&quot;\u003C/span>\n\u003Cspan class=\"hljs-built_in\">exit\u003C/span> 0\n\u003C/code>\u003C/pre>\u003Ch2 id=\"specialized-validation-scenarios\">Specialized Validation Scenarios\u003C/h2>\n\u003Ch3 id=\"multi-language-content-validation\">Multi-Language Content Validation\u003C/h3>\n\u003Cp>Handle tables with international content:\u003C/p>\n\u003Cpre>\u003Ccode class=\"hljs language-python\">\u003Cspan class=\"hljs-comment\"># international_table_validator.py - Multi-language table validation\u003C/span>\n\u003Cspan class=\"hljs-keyword\">import\u003C/span> re\n\u003Cspan class=\"hljs-keyword\">import\u003C/span> unicodedata\n\u003Cspan class=\"hljs-keyword\">from\u003C/span> typing \u003Cspan class=\"hljs-keyword\">import\u003C/span> \u003Cspan class=\"hljs-type\">Dict\u003C/span>, \u003Cspan class=\"hljs-type\">List\u003C/span>, \u003Cspan class=\"hljs-type\">Optional\u003C/span>\n\n\u003Cspan class=\"hljs-keyword\">class\u003C/span> \u003Cspan class=\"hljs-title class_\">InternationalTableValidator\u003C/span>(\u003Cspan class=\"hljs-title class_ inherited__\">TableValidator\u003C/span>):\n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">__init__\u003C/span>(\u003Cspan class=\"hljs-params\">self, schema: \u003Cspan class=\"hljs-type\">Optional\u003C/span>[\u003Cspan class=\"hljs-type\">Dict\u003C/span>] = \u003Cspan class=\"hljs-literal\">None\u003C/span>, locale: \u003Cspan class=\"hljs-built_in\">str\u003C/span> = \u003Cspan class=\"hljs-string\">&#x27;en&#x27;\u003C/span>\u003C/span>):\n        \u003Cspan class=\"hljs-built_in\">super\u003C/span>().__init__(schema)\n        self.locale = locale\n        self.setup_international_patterns()\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">setup_international_patterns\u003C/span>(\u003Cspan class=\"hljs-params\">self\u003C/span>):\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Setup locale-specific validation patterns&quot;&quot;&quot;\u003C/span>\n        \n        \u003Cspan class=\"hljs-comment\"># International phone patterns\u003C/span>\n        self.patterns[\u003Cspan class=\"hljs-string\">&#x27;phone_us&#x27;\u003C/span>] = re.\u003Cspan class=\"hljs-built_in\">compile\u003C/span>(\u003Cspan class=\"hljs-string\">r&#x27;^\\+?1?[2-9]\\d{2}[2-9]\\d{2}\\d{4}$&#x27;\u003C/span>)\n        self.patterns[\u003Cspan class=\"hljs-string\">&#x27;phone_uk&#x27;\u003C/span>] = re.\u003Cspan class=\"hljs-built_in\">compile\u003C/span>(\u003Cspan class=\"hljs-string\">r&#x27;^\\+?44[1-9]\\d{8,9}$&#x27;\u003C/span>)\n        self.patterns[\u003Cspan class=\"hljs-string\">&#x27;phone_de&#x27;\u003C/span>] = re.\u003Cspan class=\"hljs-built_in\">compile\u003C/span>(\u003Cspan class=\"hljs-string\">r&#x27;^\\+?49[1-9]\\d{10,11}$&#x27;\u003C/span>)\n        self.patterns[\u003Cspan class=\"hljs-string\">&#x27;phone_international&#x27;\u003C/span>] = re.\u003Cspan class=\"hljs-built_in\">compile\u003C/span>(\u003Cspan class=\"hljs-string\">r&#x27;^\\+[1-9]\\d{1,14}$&#x27;\u003C/span>)\n        \n        \u003Cspan class=\"hljs-comment\"># International postal codes\u003C/span>\n        self.patterns[\u003Cspan class=\"hljs-string\">&#x27;postal_us&#x27;\u003C/span>] = re.\u003Cspan class=\"hljs-built_in\">compile\u003C/span>(\u003Cspan class=\"hljs-string\">r&#x27;^\\d{5}(-\\d{4})?$&#x27;\u003C/span>)\n        self.patterns[\u003Cspan class=\"hljs-string\">&#x27;postal_uk&#x27;\u003C/span>] = re.\u003Cspan class=\"hljs-built_in\">compile\u003C/span>(\u003Cspan class=\"hljs-string\">r&#x27;^[A-Z]{1,2}\\d[A-Z\\d]?\\s*\\d[A-Z]{2}$&#x27;\u003C/span>, re.IGNORECASE)\n        self.patterns[\u003Cspan class=\"hljs-string\">&#x27;postal_de&#x27;\u003C/span>] = re.\u003Cspan class=\"hljs-built_in\">compile\u003C/span>(\u003Cspan class=\"hljs-string\">r&#x27;^\\d{5}$&#x27;\u003C/span>)\n        self.patterns[\u003Cspan class=\"hljs-string\">&#x27;postal_ca&#x27;\u003C/span>] = re.\u003Cspan class=\"hljs-built_in\">compile\u003C/span>(\u003Cspan class=\"hljs-string\">r&#x27;^[A-Z]\\d[A-Z]\\s*\\d[A-Z]\\d$&#x27;\u003C/span>, re.IGNORECASE)\n        \n        \u003Cspan class=\"hljs-comment\"># International currency patterns\u003C/span>\n        self.patterns[\u003Cspan class=\"hljs-string\">&#x27;currency_usd&#x27;\u003C/span>] = re.\u003Cspan class=\"hljs-built_in\">compile\u003C/span>(\u003Cspan class=\"hljs-string\">r&#x27;^\\$[\\d,]+\\.?\\d{0,2}$&#x27;\u003C/span>)\n        self.patterns[\u003Cspan class=\"hljs-string\">&#x27;currency_eur&#x27;\u003C/span>] = re.\u003Cspan class=\"hljs-built_in\">compile\u003C/span>(\u003Cspan class=\"hljs-string\">r&#x27;^€[\\d,]+\\.?\\d{0,2}$|^[\\d,]+\\.?\\d{0,2}€$&#x27;\u003C/span>)\n        self.patterns[\u003Cspan class=\"hljs-string\">&#x27;currency_gbp&#x27;\u003C/span>] = re.\u003Cspan class=\"hljs-built_in\">compile\u003C/span>(\u003Cspan class=\"hljs-string\">r&#x27;^£[\\d,]+\\.?\\d{0,2}$&#x27;\u003C/span>)\n        self.patterns[\u003Cspan class=\"hljs-string\">&#x27;currency_jpy&#x27;\u003C/span>] = re.\u003Cspan class=\"hljs-built_in\">compile\u003C/span>(\u003Cspan class=\"hljs-string\">r&#x27;^¥[\\d,]+$|^[\\d,]+円$&#x27;\u003C/span>)\n        \n        \u003Cspan class=\"hljs-comment\"># International date patterns\u003C/span>\n        self.patterns[\u003Cspan class=\"hljs-string\">&#x27;date_us&#x27;\u003C/span>] = re.\u003Cspan class=\"hljs-built_in\">compile\u003C/span>(\u003Cspan class=\"hljs-string\">r&#x27;^\\d{1,2}/\\d{1,2}/\\d{4}$&#x27;\u003C/span>)\n        self.patterns[\u003Cspan class=\"hljs-string\">&#x27;date_eu&#x27;\u003C/span>] = re.\u003Cspan class=\"hljs-built_in\">compile\u003C/span>(\u003Cspan class=\"hljs-string\">r&#x27;^\\d{1,2}\\.\\d{1,2}\\.\\d{4}$&#x27;\u003C/span>)\n        self.patterns[\u003Cspan class=\"hljs-string\">&#x27;date_iso&#x27;\u003C/span>] = re.\u003Cspan class=\"hljs-built_in\">compile\u003C/span>(\u003Cspan class=\"hljs-string\">r&#x27;^\\d{4}-\\d{2}-\\d{2}$&#x27;\u003C/span>)\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">validate_unicode_content\u003C/span>(\u003Cspan class=\"hljs-params\">self, content: \u003Cspan class=\"hljs-built_in\">str\u003C/span>, column: \u003Cspan class=\"hljs-built_in\">str\u003C/span>, row: \u003Cspan class=\"hljs-built_in\">int\u003C/span>\u003C/span>) -&gt; \u003Cspan class=\"hljs-type\">List\u003C/span>[ValidationResult]:\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Validate Unicode content for international text&quot;&quot;&quot;\u003C/span>\n        results = []\n        \n        \u003Cspan class=\"hljs-comment\"># Check for mixed scripts (potential data entry errors)\u003C/span>\n        scripts = \u003Cspan class=\"hljs-built_in\">set\u003C/span>()\n        \u003Cspan class=\"hljs-keyword\">for\u003C/span> char \u003Cspan class=\"hljs-keyword\">in\u003C/span> content:\n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> char.isalpha():\n                script = unicodedata.name(char, \u003Cspan class=\"hljs-string\">&#x27;&#x27;\u003C/span>).split()[\u003Cspan class=\"hljs-number\">0\u003C/span>]\n                scripts.add(script)\n        \n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-built_in\">len\u003C/span>(scripts) &gt; \u003Cspan class=\"hljs-number\">2\u003C/span>:  \u003Cspan class=\"hljs-comment\"># Allow mixing of LATIN with one other script\u003C/span>\n            results.append(ValidationResult(\n                ValidationSeverity.WARNING,\n                \u003Cspan class=\"hljs-string\">f&quot;Mixed writing systems detected: \u003Cspan class=\"hljs-subst\">{\u003Cspan class=\"hljs-string\">&#x27;, &#x27;\u003C/span>.join(scripts)}\u003C/span>&quot;\u003C/span>,\n                row=row,\n                column=column,\n                value=content\n            ))\n        \n        \u003Cspan class=\"hljs-comment\"># Check for unusual control characters\u003C/span>\n        control_chars = [char \u003Cspan class=\"hljs-keyword\">for\u003C/span> char \u003Cspan class=\"hljs-keyword\">in\u003C/span> content \u003Cspan class=\"hljs-keyword\">if\u003C/span> unicodedata.category(char).startswith(\u003Cspan class=\"hljs-string\">&#x27;C&#x27;\u003C/span>)]\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> control_chars:\n            results.append(ValidationResult(\n                ValidationSeverity.WARNING,\n                \u003Cspan class=\"hljs-string\">f&quot;Control characters found: \u003Cspan class=\"hljs-subst\">{[\u003Cspan class=\"hljs-built_in\">hex\u003C/span>(\u003Cspan class=\"hljs-built_in\">ord\u003C/span>(c)) \u003Cspan class=\"hljs-keyword\">for\u003C/span> c \u003Cspan class=\"hljs-keyword\">in\u003C/span> control_chars]}\u003C/span>&quot;\u003C/span>,\n                row=row,\n                column=column,\n                value=content\n            ))\n        \n        \u003Cspan class=\"hljs-comment\"># Check text direction consistency\u003C/span>\n        has_rtl = \u003Cspan class=\"hljs-built_in\">any\u003C/span>(unicodedata.bidirectional(char) \u003Cspan class=\"hljs-keyword\">in\u003C/span> [\u003Cspan class=\"hljs-string\">&#x27;R&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;AL&#x27;\u003C/span>] \u003Cspan class=\"hljs-keyword\">for\u003C/span> char \u003Cspan class=\"hljs-keyword\">in\u003C/span> content)\n        has_ltr = \u003Cspan class=\"hljs-built_in\">any\u003C/span>(unicodedata.bidirectional(char) == \u003Cspan class=\"hljs-string\">&#x27;L&#x27;\u003C/span> \u003Cspan class=\"hljs-keyword\">for\u003C/span> char \u003Cspan class=\"hljs-keyword\">in\u003C/span> content)\n        \n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> has_rtl \u003Cspan class=\"hljs-keyword\">and\u003C/span> has_ltr:\n            results.append(ValidationResult(\n                ValidationSeverity.INFO,\n                \u003Cspan class=\"hljs-string\">&quot;Mixed text direction (LTR and RTL) detected&quot;\u003C/span>,\n                row=row,\n                column=column,\n                value=content\n            ))\n        \n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> results\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">validate_locale_specific_formats\u003C/span>(\u003Cspan class=\"hljs-params\">self, content: \u003Cspan class=\"hljs-built_in\">str\u003C/span>, column: \u003Cspan class=\"hljs-built_in\">str\u003C/span>, row: \u003Cspan class=\"hljs-built_in\">int\u003C/span>, \n                                       expected_locale: \u003Cspan class=\"hljs-built_in\">str\u003C/span>\u003C/span>) -&gt; \u003Cspan class=\"hljs-type\">List\u003C/span>[ValidationResult]:\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Validate locale-specific formatting&quot;&quot;&quot;\u003C/span>\n        results = []\n        \n        \u003Cspan class=\"hljs-comment\"># Validate phone numbers by locale\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;phone&#x27;\u003C/span> \u003Cspan class=\"hljs-keyword\">in\u003C/span> column.lower():\n            phone_pattern = \u003Cspan class=\"hljs-string\">f&#x27;phone_\u003Cspan class=\"hljs-subst\">{expected_locale}\u003C/span>&#x27;\u003C/span>\n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> phone_pattern \u003Cspan class=\"hljs-keyword\">in\u003C/span> self.patterns:\n                \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-keyword\">not\u003C/span> self.patterns[phone_pattern].\u003Cspan class=\"hljs-keyword\">match\u003C/span>(content.strip()):\n                    results.append(ValidationResult(\n                        ValidationSeverity.ERROR,\n                        \u003Cspan class=\"hljs-string\">f&quot;Invalid phone format for locale \u003Cspan class=\"hljs-subst\">{expected_locale}\u003C/span>&quot;\u003C/span>,\n                        row=row,\n                        column=column,\n                        value=content\n                    ))\n        \n        \u003Cspan class=\"hljs-comment\"># Validate postal codes by locale\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;postal&#x27;\u003C/span> \u003Cspan class=\"hljs-keyword\">in\u003C/span> column.lower() \u003Cspan class=\"hljs-keyword\">or\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;zip&#x27;\u003C/span> \u003Cspan class=\"hljs-keyword\">in\u003C/span> column.lower():\n            postal_pattern = \u003Cspan class=\"hljs-string\">f&#x27;postal_\u003Cspan class=\"hljs-subst\">{expected_locale}\u003C/span>&#x27;\u003C/span>\n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> postal_pattern \u003Cspan class=\"hljs-keyword\">in\u003C/span> self.patterns:\n                \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-keyword\">not\u003C/span> self.patterns[postal_pattern].\u003Cspan class=\"hljs-keyword\">match\u003C/span>(content.strip()):\n                    results.append(ValidationResult(\n                        ValidationSeverity.ERROR,\n                        \u003Cspan class=\"hljs-string\">f&quot;Invalid postal code format for locale \u003Cspan class=\"hljs-subst\">{expected_locale}\u003C/span>&quot;\u003C/span>,\n                        row=row,\n                        column=column,\n                        value=content\n                    ))\n        \n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> results\n\n\u003Cspan class=\"hljs-comment\"># Example usage for international validation\u003C/span>\n\u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">demonstrate_international_validation\u003C/span>():\n    \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Demonstrate international table validation&quot;&quot;&quot;\u003C/span>\n    \n    international_table = \u003Cspan class=\"hljs-string\">&#x27;&#x27;&#x27;\n| Name | Country | Phone | Postal Code | Currency |\n|------|---------|-------|-------------|----------|\n| John Smith | US | +1-555-123-4567 | 10001 | $1,234.56 |\n| Marie Dubois | FR | +33-1-42-86-83-26 | 75001 | €987.65 |\n| 田中太郎 | JP | +81-3-1234-5678 | 100-0001 | ¥50,000 |\n| Invalid Entry | UK | 123-456 | INVALID | $50 |\n    &#x27;&#x27;&#x27;\u003C/span>\n    \n    \u003Cspan class=\"hljs-comment\"># Create international validator\u003C/span>\n    validator = InternationalTableValidator()\n    \n    \u003Cspan class=\"hljs-comment\"># Define schema with locale expectations\u003C/span>\n    international_schema = {\n        \u003Cspan class=\"hljs-string\">&#x27;columns&#x27;\u003C/span>: {\n            \u003Cspan class=\"hljs-string\">&#x27;Name&#x27;\u003C/span>: {\n                \u003Cspan class=\"hljs-string\">&#x27;required&#x27;\u003C/span>: \u003Cspan class=\"hljs-literal\">True\u003C/span>,\n                \u003Cspan class=\"hljs-string\">&#x27;validate_unicode&#x27;\u003C/span>: \u003Cspan class=\"hljs-literal\">True\u003C/span>\n            },\n            \u003Cspan class=\"hljs-string\">&#x27;Country&#x27;\u003C/span>: {\n                \u003Cspan class=\"hljs-string\">&#x27;required&#x27;\u003C/span>: \u003Cspan class=\"hljs-literal\">True\u003C/span>,\n                \u003Cspan class=\"hljs-string\">&#x27;allowed_values&#x27;\u003C/span>: [\u003Cspan class=\"hljs-string\">&#x27;US&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;FR&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;JP&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;UK&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;DE&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;CA&#x27;\u003C/span>]\n            },\n            \u003Cspan class=\"hljs-string\">&#x27;Phone&#x27;\u003C/span>: {\n                \u003Cspan class=\"hljs-string\">&#x27;required&#x27;\u003C/span>: \u003Cspan class=\"hljs-literal\">True\u003C/span>,\n                \u003Cspan class=\"hljs-string\">&#x27;locale_specific&#x27;\u003C/span>: \u003Cspan class=\"hljs-literal\">True\u003C/span>\n            },\n            \u003Cspan class=\"hljs-string\">&#x27;Postal Code&#x27;\u003C/span>: {\n                \u003Cspan class=\"hljs-string\">&#x27;required&#x27;\u003C/span>: \u003Cspan class=\"hljs-literal\">True\u003C/span>,\n                \u003Cspan class=\"hljs-string\">&#x27;locale_specific&#x27;\u003C/span>: \u003Cspan class=\"hljs-literal\">True\u003C/span>\n            },\n            \u003Cspan class=\"hljs-string\">&#x27;Currency&#x27;\u003C/span>: {\n                \u003Cspan class=\"hljs-string\">&#x27;required&#x27;\u003C/span>: \u003Cspan class=\"hljs-literal\">True\u003C/span>,\n                \u003Cspan class=\"hljs-string\">&#x27;locale_specific&#x27;\u003C/span>: \u003Cspan class=\"hljs-literal\">True\u003C/span>\n            }\n        }\n    }\n    \n    \u003Cspan class=\"hljs-built_in\">print\u003C/span>(\u003Cspan class=\"hljs-string\">&quot;International Table Validation:&quot;\u003C/span>)\n    \u003Cspan class=\"hljs-built_in\">print\u003C/span>(international_table)\n    \n    \u003Cspan class=\"hljs-comment\"># Validate structure and content\u003C/span>\n    structure_results = validator.validate_table_structure(international_table)\n    content_results = validator.validate_table_content(international_table, international_schema)\n    \n    \u003Cspan class=\"hljs-comment\"># Add Unicode validation\u003C/span>\n    table_data = validator._parse_table_to_dict(international_table)\n    \u003Cspan class=\"hljs-keyword\">for\u003C/span> row_idx, row \u003Cspan class=\"hljs-keyword\">in\u003C/span> \u003Cspan class=\"hljs-built_in\">enumerate\u003C/span>(table_data[\u003Cspan class=\"hljs-string\">&#x27;rows&#x27;\u003C/span>], \u003Cspan class=\"hljs-number\">1\u003C/span>):\n        \u003Cspan class=\"hljs-keyword\">for\u003C/span> col_idx, (header, cell_value) \u003Cspan class=\"hljs-keyword\">in\u003C/span> \u003Cspan class=\"hljs-built_in\">enumerate\u003C/span>(\u003Cspan class=\"hljs-built_in\">zip\u003C/span>(table_data[\u003Cspan class=\"hljs-string\">&#x27;headers&#x27;\u003C/span>], row)):\n            unicode_results = validator.validate_unicode_content(cell_value, header, row_idx + \u003Cspan class=\"hljs-number\">2\u003C/span>)\n            content_results.extend(unicode_results)\n    \n    all_results = structure_results + content_results\n    \n    \u003Cspan class=\"hljs-keyword\">for\u003C/span> result \u003Cspan class=\"hljs-keyword\">in\u003C/span> all_results:\n        severity_icon = {\u003Cspan class=\"hljs-string\">&#x27;error&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;❌&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;warning&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;⚠️&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;info&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;ℹ️&#x27;\u003C/span>}\n        icon = severity_icon.get(result.severity.value, \u003Cspan class=\"hljs-string\">&#x27;•&#x27;\u003C/span>)\n        location = \u003Cspan class=\"hljs-string\">f&quot;Row \u003Cspan class=\"hljs-subst\">{result.row}\u003C/span>, Column &#x27;\u003Cspan class=\"hljs-subst\">{result.column}\u003C/span>&#x27;&quot;\u003C/span> \u003Cspan class=\"hljs-keyword\">if\u003C/span> result.row \u003Cspan class=\"hljs-keyword\">and\u003C/span> result.column \u003Cspan class=\"hljs-keyword\">else\u003C/span> \u003Cspan class=\"hljs-string\">&quot;&quot;\u003C/span>\n        \u003Cspan class=\"hljs-built_in\">print\u003C/span>(\u003Cspan class=\"hljs-string\">f&quot;\u003Cspan class=\"hljs-subst\">{icon}\u003C/span> \u003Cspan class=\"hljs-subst\">{result.message}\u003C/span>&quot;\u003C/span>)\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> location \u003Cspan class=\"hljs-keyword\">and\u003C/span> result.value:\n            \u003Cspan class=\"hljs-built_in\">print\u003C/span>(\u003Cspan class=\"hljs-string\">f&quot;   \u003Cspan class=\"hljs-subst\">{location}\u003C/span>: &#x27;\u003Cspan class=\"hljs-subst\">{result.value}\u003C/span>&#x27;&quot;\u003C/span>)\n\n\u003Cspan class=\"hljs-keyword\">if\u003C/span> __name__ == \u003Cspan class=\"hljs-string\">&quot;__main__&quot;\u003C/span>:\n    demonstrate_international_validation()\n\u003C/code>\u003C/pre>\u003Ch2 id=\"integration-with-documentation-workflows\">Integration with Documentation Workflows\u003C/h2>\n\u003Cp>Table validation integrates seamlessly with comprehensive Markdown documentation systems. When combined with \u003Ca href=\"/blog/markdown-table-borders-styling-complete-guide\">table styling and formatting techniques\u003C/a>, automated validation ensures that styled tables maintain both visual appeal and data integrity across different rendering contexts and platforms.\u003C/p>\n\u003Cp>For projects requiring both data validation and complex table layouts, validation workflows complement \u003Ca href=\"/blog/markdown-table-responsive-design-complete-guide\">responsive table design principles\u003C/a> by ensuring that table content remains accurate and consistent while adapting to different screen sizes and viewing environments.\u003C/p>\n\u003Cp>When building comprehensive documentation systems, table validation works effectively with \u003Ca href=\"/blog/markdown-metadata-yaml-frontmatter-complete-guide\">metadata and frontmatter management\u003C/a> to create structured documentation workflows that validate both table content and document metadata for complete quality assurance coverage.\u003C/p>\n\u003Ch2 id=\"troubleshooting-validation-issues\">Troubleshooting Validation Issues\u003C/h2>\n\u003Ch3 id=\"common-validation-failures\">Common Validation Failures\u003C/h3>\n\u003Cp>\u003Cstrong>Problem\u003C/strong>: False positive validation errors\u003Cbr>\u003Cstrong>Solutions\u003C/strong>:\u003C/p>\n\u003Cpre>\u003Ccode class=\"hljs language-markdown\">\u003Cspan class=\"hljs-section\"># Debugging False Positives\u003C/span>\n\n\u003Cspan class=\"hljs-section\">## Check Schema Definitions\u003C/span>\n\u003Cspan class=\"hljs-bullet\">1.\u003C/span> Verify column names match exactly (case-sensitive)\n\u003Cspan class=\"hljs-bullet\">2.\u003C/span> Ensure allowed values include all valid options\n\u003Cspan class=\"hljs-bullet\">3.\u003C/span> Review pattern matching for edge cases\n\u003Cspan class=\"hljs-bullet\">4.\u003C/span> Test with minimal valid examples\n\n\u003Cspan class=\"hljs-section\">## Review Content Formatting\u003C/span>\n\u003Cspan class=\"hljs-bullet\">1.\u003C/span> Check for hidden characters or extra whitespace\n\u003Cspan class=\"hljs-bullet\">2.\u003C/span> Verify consistent data formatting\n\u003Cspan class=\"hljs-bullet\">3.\u003C/span> Look for copy-paste artifacts\n\u003Cspan class=\"hljs-bullet\">4.\u003C/span> Validate Unicode normalization\n\n\u003Cspan class=\"hljs-section\">## Debug Validation Logic\u003C/span>\n\u003Cspan class=\"hljs-bullet\">1.\u003C/span> Enable verbose logging\n\u003Cspan class=\"hljs-bullet\">2.\u003C/span> Test individual validation rules\n\u003Cspan class=\"hljs-bullet\">3.\u003C/span> Use validation debugging mode\n\u003Cspan class=\"hljs-bullet\">4.\u003C/span> Review validation order dependencies\n\u003C/code>\u003C/pre>\u003Ch3 id=\"performance-optimization\">Performance Optimization\u003C/h3>\n\u003Cp>\u003Cstrong>Problem\u003C/strong>: Slow validation on large repositories\u003Cbr>\u003Cstrong>Solutions\u003C/strong>:\u003C/p>\n\u003Cpre>\u003Ccode class=\"hljs language-markdown\">\u003Cspan class=\"hljs-section\"># Optimizing Validation Performance\u003C/span>\n\n\u003Cspan class=\"hljs-section\">## Selective Validation\u003C/span>\n\u003Cspan class=\"hljs-bullet\">-\u003C/span> Only validate changed files in CI\n\u003Cspan class=\"hljs-bullet\">-\u003C/span> Use file modification timestamps\n\u003Cspan class=\"hljs-bullet\">-\u003C/span> Implement validation caching\n\u003Cspan class=\"hljs-bullet\">-\u003C/span> Skip unchanged content validation\n\n\u003Cspan class=\"hljs-section\">## Parallel Processing\u003C/span>\n\u003Cspan class=\"hljs-bullet\">-\u003C/span> Validate multiple files concurrently\n\u003Cspan class=\"hljs-bullet\">-\u003C/span> Use process pools for CPU-intensive validation\n\u003Cspan class=\"hljs-bullet\">-\u003C/span> Implement async validation for I/O operations\n\u003Cspan class=\"hljs-bullet\">-\u003C/span> Batch process similar validation tasks\n\n\u003Cspan class=\"hljs-section\">## Smart Caching\u003C/span>\n\u003Cspan class=\"hljs-bullet\">-\u003C/span> Cache validation results by file hash\n\u003Cspan class=\"hljs-bullet\">-\u003C/span> Store schema compilation results\n\u003Cspan class=\"hljs-bullet\">-\u003C/span> Implement validation result persistence\n\u003Cspan class=\"hljs-bullet\">-\u003C/span> Use distributed caching for team workflows\n\u003C/code>\u003C/pre>\u003Ch2 id=\"advanced-quality-assurance-workflows\">Advanced Quality Assurance Workflows\u003C/h2>\n\u003Ch3 id=\"continuous-quality-monitoring\">Continuous Quality Monitoring\u003C/h3>\n\u003Cpre>\u003Ccode class=\"hljs language-python\">\u003Cspan class=\"hljs-comment\"># quality_monitor.py - Continuous table quality monitoring\u003C/span>\n\u003Cspan class=\"hljs-keyword\">import\u003C/span> time\n\u003Cspan class=\"hljs-keyword\">import\u003C/span> json\n\u003Cspan class=\"hljs-keyword\">from\u003C/span> datetime \u003Cspan class=\"hljs-keyword\">import\u003C/span> datetime, timedelta\n\u003Cspan class=\"hljs-keyword\">from\u003C/span> pathlib \u003Cspan class=\"hljs-keyword\">import\u003C/span> Path\n\u003Cspan class=\"hljs-keyword\">from\u003C/span> typing \u003Cspan class=\"hljs-keyword\">import\u003C/span> \u003Cspan class=\"hljs-type\">Dict\u003C/span>, \u003Cspan class=\"hljs-type\">List\u003C/span>\n\u003Cspan class=\"hljs-keyword\">import\u003C/span> sqlite3\n\n\u003Cspan class=\"hljs-keyword\">class\u003C/span> \u003Cspan class=\"hljs-title class_\">TableQualityMonitor\u003C/span>:\n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">__init__\u003C/span>(\u003Cspan class=\"hljs-params\">self, db_path: \u003Cspan class=\"hljs-built_in\">str\u003C/span> = \u003Cspan class=\"hljs-string\">&#x27;table_quality.db&#x27;\u003C/span>\u003C/span>):\n        self.db_path = db_path\n        self.validator = TableValidator()\n        self.setup_database()\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">setup_database\u003C/span>(\u003Cspan class=\"hljs-params\">self\u003C/span>):\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Initialize quality monitoring database&quot;&quot;&quot;\u003C/span>\n        conn = sqlite3.connect(self.db_path)\n        cursor = conn.cursor()\n        \n        cursor.execute(\u003Cspan class=\"hljs-string\">&#x27;&#x27;&#x27;\n            CREATE TABLE IF NOT EXISTS quality_metrics (\n                id INTEGER PRIMARY KEY AUTOINCREMENT,\n                timestamp TEXT NOT NULL,\n                file_path TEXT NOT NULL,\n                table_count INTEGER NOT NULL,\n                error_count INTEGER NOT NULL,\n                warning_count INTEGER NOT NULL,\n                validation_duration REAL NOT NULL,\n                file_hash TEXT NOT NULL\n            )\n        &#x27;&#x27;&#x27;\u003C/span>)\n        \n        cursor.execute(\u003Cspan class=\"hljs-string\">&#x27;&#x27;&#x27;\n            CREATE TABLE IF NOT EXISTS quality_trends (\n                date TEXT PRIMARY KEY,\n                total_files INTEGER NOT NULL,\n                total_tables INTEGER NOT NULL,\n                total_errors INTEGER NOT NULL,\n                total_warnings INTEGER NOT NULL,\n                avg_errors_per_file REAL NOT NULL,\n                files_with_errors INTEGER NOT NULL\n            )\n        &#x27;&#x27;&#x27;\u003C/span>)\n        \n        conn.commit()\n        conn.close()\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">monitor_repository\u003C/span>(\u003Cspan class=\"hljs-params\">self, repo_path: Path\u003C/span>) -&gt; \u003Cspan class=\"hljs-type\">Dict\u003C/span>:\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Monitor repository table quality over time&quot;&quot;&quot;\u003C/span>\n        start_time = time.time()\n        \n        \u003Cspan class=\"hljs-comment\"># Validate all tables\u003C/span>\n        ci_validator = CITableValidator()\n        results = ci_validator.validate_repository(repo_path)\n        \n        validation_duration = time.time() - start_time\n        \n        \u003Cspan class=\"hljs-comment\"># Store detailed metrics\u003C/span>\n        self._store_file_metrics(results, validation_duration)\n        \n        \u003Cspan class=\"hljs-comment\"># Update trend data\u003C/span>\n        self._update_trend_data(results)\n        \n        \u003Cspan class=\"hljs-comment\"># Generate quality report\u003C/span>\n        quality_report = self._generate_quality_report(results)\n        \n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> quality_report\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">_store_file_metrics\u003C/span>(\u003Cspan class=\"hljs-params\">self, results: \u003Cspan class=\"hljs-type\">Dict\u003C/span>, duration: \u003Cspan class=\"hljs-built_in\">float\u003C/span>\u003C/span>):\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Store per-file quality metrics&quot;&quot;&quot;\u003C/span>\n        conn = sqlite3.connect(self.db_path)\n        cursor = conn.cursor()\n        \n        timestamp = datetime.now().isoformat()\n        \n        \u003Cspan class=\"hljs-keyword\">for\u003C/span> file_result \u003Cspan class=\"hljs-keyword\">in\u003C/span> results[\u003Cspan class=\"hljs-string\">&#x27;validation_details&#x27;\u003C/span>]:\n            file_path = file_result[\u003Cspan class=\"hljs-string\">&#x27;file&#x27;\u003C/span>]\n            file_hash = self._calculate_file_hash(file_path)\n            \n            cursor.execute(\u003Cspan class=\"hljs-string\">&#x27;&#x27;&#x27;\n                INSERT INTO quality_metrics \n                (timestamp, file_path, table_count, error_count, warning_count, validation_duration, file_hash)\n                VALUES (?, ?, ?, ?, ?, ?, ?)\n            &#x27;&#x27;&#x27;\u003C/span>, (\n                timestamp,\n                file_path,\n                file_result[\u003Cspan class=\"hljs-string\">&#x27;tables_found&#x27;\u003C/span>],\n                file_result[\u003Cspan class=\"hljs-string\">&#x27;summary&#x27;\u003C/span>][\u003Cspan class=\"hljs-string\">&#x27;errors&#x27;\u003C/span>],\n                file_result[\u003Cspan class=\"hljs-string\">&#x27;summary&#x27;\u003C/span>][\u003Cspan class=\"hljs-string\">&#x27;warnings&#x27;\u003C/span>],\n                duration,\n                file_hash\n            ))\n        \n        conn.commit()\n        conn.close()\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">_update_trend_data\u003C/span>(\u003Cspan class=\"hljs-params\">self, results: \u003Cspan class=\"hljs-type\">Dict\u003C/span>\u003C/span>):\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Update daily trend statistics&quot;&quot;&quot;\u003C/span>\n        conn = sqlite3.connect(self.db_path)\n        cursor = conn.cursor()\n        \n        today = datetime.now().date().isoformat()\n        \n        \u003Cspan class=\"hljs-comment\"># Calculate daily metrics\u003C/span>\n        total_files = results[\u003Cspan class=\"hljs-string\">&#x27;files_processed&#x27;\u003C/span>]\n        total_tables = results[\u003Cspan class=\"hljs-string\">&#x27;tables_validated&#x27;\u003C/span>]\n        total_errors = results[\u003Cspan class=\"hljs-string\">&#x27;total_errors&#x27;\u003C/span>]\n        total_warnings = results[\u003Cspan class=\"hljs-string\">&#x27;total_warnings&#x27;\u003C/span>]\n        avg_errors_per_file = total_errors / total_files \u003Cspan class=\"hljs-keyword\">if\u003C/span> total_files &gt; \u003Cspan class=\"hljs-number\">0\u003C/span> \u003Cspan class=\"hljs-keyword\">else\u003C/span> \u003Cspan class=\"hljs-number\">0\u003C/span>\n        files_with_errors = \u003Cspan class=\"hljs-built_in\">len\u003C/span>(results[\u003Cspan class=\"hljs-string\">&#x27;files_with_errors&#x27;\u003C/span>])\n        \n        cursor.execute(\u003Cspan class=\"hljs-string\">&#x27;&#x27;&#x27;\n            INSERT OR REPLACE INTO quality_trends\n            (date, total_files, total_tables, total_errors, total_warnings, avg_errors_per_file, files_with_errors)\n            VALUES (?, ?, ?, ?, ?, ?, ?)\n        &#x27;&#x27;&#x27;\u003C/span>, (\n            today, total_files, total_tables, total_errors, \n            total_warnings, avg_errors_per_file, files_with_errors\n        ))\n        \n        conn.commit()\n        conn.close()\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">generate_quality_dashboard\u003C/span>(\u003Cspan class=\"hljs-params\">self\u003C/span>) -&gt; \u003Cspan class=\"hljs-built_in\">str\u003C/span>:\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Generate quality dashboard with trends&quot;&quot;&quot;\u003C/span>\n        conn = sqlite3.connect(self.db_path)\n        cursor = conn.cursor()\n        \n        \u003Cspan class=\"hljs-comment\"># Get recent trends (last 30 days)\u003C/span>\n        thirty_days_ago = (datetime.now() - timedelta(days=\u003Cspan class=\"hljs-number\">30\u003C/span>)).date().isoformat()\n        \n        cursor.execute(\u003Cspan class=\"hljs-string\">&#x27;&#x27;&#x27;\n            SELECT date, total_errors, total_warnings, files_with_errors, total_files\n            FROM quality_trends \n            WHERE date &gt;= ?\n            ORDER BY date\n        &#x27;&#x27;&#x27;\u003C/span>, (thirty_days_ago,))\n        \n        trend_data = cursor.fetchall()\n        \n        \u003Cspan class=\"hljs-comment\"># Get current quality snapshot\u003C/span>\n        cursor.execute(\u003Cspan class=\"hljs-string\">&#x27;&#x27;&#x27;\n            SELECT \n                COUNT(DISTINCT file_path) as total_files,\n                SUM(table_count) as total_tables,\n                SUM(error_count) as total_errors,\n                SUM(warning_count) as total_warnings\n            FROM quality_metrics \n            WHERE date(timestamp) = date(&#x27;now&#x27;)\n        &#x27;&#x27;&#x27;\u003C/span>)\n        \n        current_snapshot = cursor.fetchone()\n        \n        conn.close()\n        \n        \u003Cspan class=\"hljs-comment\"># Generate dashboard\u003C/span>\n        dashboard = []\n        dashboard.append(\u003Cspan class=\"hljs-string\">&quot;# Table Quality Dashboard&quot;\u003C/span>)\n        dashboard.append(\u003Cspan class=\"hljs-string\">&quot;&quot;\u003C/span>)\n        \n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> current_snapshot \u003Cspan class=\"hljs-keyword\">and\u003C/span> \u003Cspan class=\"hljs-built_in\">any\u003C/span>(current_snapshot):\n            dashboard.append(\u003Cspan class=\"hljs-string\">&quot;## Current Status&quot;\u003C/span>)\n            dashboard.append(\u003Cspan class=\"hljs-string\">f&quot;- **Files Monitored**: \u003Cspan class=\"hljs-subst\">{current_snapshot[\u003Cspan class=\"hljs-number\">0\u003C/span>] \u003Cspan class=\"hljs-keyword\">or\u003C/span> \u003Cspan class=\"hljs-number\">0\u003C/span>}\u003C/span>&quot;\u003C/span>)\n            dashboard.append(\u003Cspan class=\"hljs-string\">f&quot;- **Tables Validated**: \u003Cspan class=\"hljs-subst\">{current_snapshot[\u003Cspan class=\"hljs-number\">1\u003C/span>] \u003Cspan class=\"hljs-keyword\">or\u003C/span> \u003Cspan class=\"hljs-number\">0\u003C/span>}\u003C/span>&quot;\u003C/span>)\n            dashboard.append(\u003Cspan class=\"hljs-string\">f&quot;- **Active Errors**: \u003Cspan class=\"hljs-subst\">{current_snapshot[\u003Cspan class=\"hljs-number\">2\u003C/span>] \u003Cspan class=\"hljs-keyword\">or\u003C/span> \u003Cspan class=\"hljs-number\">0\u003C/span>}\u003C/span>&quot;\u003C/span>)\n            dashboard.append(\u003Cspan class=\"hljs-string\">f&quot;- **Active Warnings**: \u003Cspan class=\"hljs-subst\">{current_snapshot[\u003Cspan class=\"hljs-number\">3\u003C/span>] \u003Cspan class=\"hljs-keyword\">or\u003C/span> \u003Cspan class=\"hljs-number\">0\u003C/span>}\u003C/span>&quot;\u003C/span>)\n            dashboard.append(\u003Cspan class=\"hljs-string\">&quot;&quot;\u003C/span>)\n        \n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> trend_data:\n            dashboard.append(\u003Cspan class=\"hljs-string\">&quot;## 30-Day Trend&quot;\u003C/span>)\n            dashboard.append(\u003Cspan class=\"hljs-string\">&quot;| Date | Errors | Warnings | Files with Issues | Total Files |&quot;\u003C/span>)\n            dashboard.append(\u003Cspan class=\"hljs-string\">&quot;|------|---------|----------|-------------------|-------------|&quot;\u003C/span>)\n            \n            \u003Cspan class=\"hljs-keyword\">for\u003C/span> date, errors, warnings, files_with_errors, total_files \u003Cspan class=\"hljs-keyword\">in\u003C/span> trend_data:\n                dashboard.append(\u003Cspan class=\"hljs-string\">f&quot;| \u003Cspan class=\"hljs-subst\">{date}\u003C/span> | \u003Cspan class=\"hljs-subst\">{errors}\u003C/span> | \u003Cspan class=\"hljs-subst\">{warnings}\u003C/span> | \u003Cspan class=\"hljs-subst\">{files_with_errors}\u003C/span> | \u003Cspan class=\"hljs-subst\">{total_files}\u003C/span> |&quot;\u003C/span>)\n            \n            dashboard.append(\u003Cspan class=\"hljs-string\">&quot;&quot;\u003C/span>)\n            \n            \u003Cspan class=\"hljs-comment\"># Calculate trend direction\u003C/span>\n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-built_in\">len\u003C/span>(trend_data) &gt;= \u003Cspan class=\"hljs-number\">2\u003C/span>:\n                recent_errors = trend_data[-\u003Cspan class=\"hljs-number\">1\u003C/span>][\u003Cspan class=\"hljs-number\">1\u003C/span>]\n                previous_errors = trend_data[-\u003Cspan class=\"hljs-number\">2\u003C/span>][\u003Cspan class=\"hljs-number\">1\u003C/span>]\n                \n                \u003Cspan class=\"hljs-keyword\">if\u003C/span> recent_errors &lt; previous_errors:\n                    trend = \u003Cspan class=\"hljs-string\">&quot;📈 Improving&quot;\u003C/span>\n                \u003Cspan class=\"hljs-keyword\">elif\u003C/span> recent_errors &gt; previous_errors:\n                    trend = \u003Cspan class=\"hljs-string\">&quot;📉 Declining&quot;\u003C/span>\n                \u003Cspan class=\"hljs-keyword\">else\u003C/span>:\n                    trend = \u003Cspan class=\"hljs-string\">&quot;➡️ Stable&quot;\u003C/span>\n                \n                dashboard.append(\u003Cspan class=\"hljs-string\">f&quot;**Quality Trend**: \u003Cspan class=\"hljs-subst\">{trend}\u003C/span>&quot;\u003C/span>)\n        \n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;\\n&#x27;\u003C/span>.join(dashboard)\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">_calculate_file_hash\u003C/span>(\u003Cspan class=\"hljs-params\">self, file_path: \u003Cspan class=\"hljs-built_in\">str\u003C/span>\u003C/span>) -&gt; \u003Cspan class=\"hljs-built_in\">str\u003C/span>:\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Calculate file hash for change detection&quot;&quot;&quot;\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">import\u003C/span> hashlib\n        \u003Cspan class=\"hljs-keyword\">try\u003C/span>:\n            \u003Cspan class=\"hljs-keyword\">with\u003C/span> \u003Cspan class=\"hljs-built_in\">open\u003C/span>(file_path, \u003Cspan class=\"hljs-string\">&#x27;rb&#x27;\u003C/span>) \u003Cspan class=\"hljs-keyword\">as\u003C/span> f:\n                \u003Cspan class=\"hljs-keyword\">return\u003C/span> hashlib.md5(f.read()).hexdigest()\n        \u003Cspan class=\"hljs-keyword\">except\u003C/span>:\n            \u003Cspan class=\"hljs-keyword\">return\u003C/span> \u003Cspan class=\"hljs-string\">&quot;&quot;\u003C/span>\n\n\u003Cspan class=\"hljs-comment\"># Usage example for quality monitoring\u003C/span>\n\u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">setup_quality_monitoring\u003C/span>():\n    \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Setup continuous quality monitoring&quot;&quot;&quot;\u003C/span>\n    monitor = TableQualityMonitor()\n    \n    \u003Cspan class=\"hljs-comment\"># Monitor repository\u003C/span>\n    repo_path = Path(\u003Cspan class=\"hljs-string\">&#x27;.&#x27;\u003C/span>)\n    quality_report = monitor.monitor_repository(repo_path)\n    \n    \u003Cspan class=\"hljs-comment\"># Generate dashboard\u003C/span>\n    dashboard = monitor.generate_quality_dashboard()\n    \n    \u003Cspan class=\"hljs-comment\"># Save dashboard to file\u003C/span>\n    \u003Cspan class=\"hljs-keyword\">with\u003C/span> \u003Cspan class=\"hljs-built_in\">open\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;quality-dashboard.md&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;w&#x27;\u003C/span>) \u003Cspan class=\"hljs-keyword\">as\u003C/span> f:\n        f.write(dashboard)\n    \n    \u003Cspan class=\"hljs-built_in\">print\u003C/span>(\u003Cspan class=\"hljs-string\">&quot;Quality monitoring completed. Dashboard saved to quality-dashboard.md&quot;\u003C/span>)\n    \n    \u003Cspan class=\"hljs-keyword\">return\u003C/span> quality_report\n\n\u003Cspan class=\"hljs-keyword\">if\u003C/span> __name__ == \u003Cspan class=\"hljs-string\">&quot;__main__&quot;\u003C/span>:\n    setup_quality_monitoring()\n\u003C/code>\u003C/pre>\u003Ch2 id=\"conclusion\">Conclusion\u003C/h2>\n\u003Cp>Markdown table data validation and quality assurance create robust, maintainable documentation systems that ensure data integrity while supporting collaborative workflows and automated quality control. By implementing comprehensive validation frameworks, schema-based content verification, and continuous monitoring systems, technical teams can maintain high-quality table content that serves users reliably across different platforms and use cases.\u003C/p>\n\u003Cp>The key to successful table validation lies in balancing thoroughness with practicality, implementing validation rules that catch genuine errors without creating excessive friction in content creation workflows. Whether you&#39;re managing financial reports, user directories, or product catalogs, the validation techniques covered in this guide provide the foundation for professional documentation that maintains accuracy and consistency at scale.\u003C/p>\n\u003Cp>Remember to adapt validation rules to your specific content requirements, implement appropriate error handling and reporting mechanisms, and integrate validation workflows into your development and deployment processes. With proper table validation systems in place, your Markdown documentation becomes a trustworthy source of structured information that supports critical business processes and decision-making activities.\u003C/p>\n",[15,19,22,25,28,31,34,37,40],{"id":16,"text":17,"level":18},"why-implement-table-data-validation","Why Implement Table Data Validation?",2,{"id":20,"text":21,"level":18},"foundation-table-validation-concepts","Foundation Table Validation Concepts",{"id":23,"text":24,"level":18},"advanced-validation-implementation","Advanced Validation Implementation",{"id":26,"text":27,"level":18},"platform-integration-workflows","Platform Integration Workflows",{"id":29,"text":30,"level":18},"specialized-validation-scenarios","Specialized Validation Scenarios",{"id":32,"text":33,"level":18},"integration-with-documentation-workflows","Integration with Documentation Workflows",{"id":35,"text":36,"level":18},"troubleshooting-validation-issues","Troubleshooting Validation Issues",{"id":38,"text":39,"level":18},"advanced-quality-assurance-workflows","Advanced Quality Assurance Workflows",{"id":41,"text":42,"level":18},"conclusion","Conclusion",[],[45,53,61],{"slug":46,"title":47,"description":48,"excerpt":49,"date":50,"category":9,"author":10,"keywords":51,"readingMinutes":52},"markdown-data-validation-and-schema-checking-complete-guide","Markdown Data Validation and Schema Checking: Complete Guide for Content Quality Assurance and Automated Verification","Master advanced Markdown data validation techniques using schema checking, frontmatter validation, content structure verification, and automated quality assurance systems. Learn to implement robust validation workflows for documentation teams.","Advanced Markdown data validation and schema checking enables sophisticated content quality assurance systems that automatically verify document structure, validate metadata consistency, and…","2025-10-27","markdown data validation, schema checking markdown, frontmatter validation, markdown content verification, automated markdown quality, documentation validation, markdown schema, content structure validation",19,{"slug":54,"title":55,"description":56,"excerpt":57,"date":58,"category":9,"author":10,"keywords":59,"readingMinutes":60},"markdown-table-data-validation-quality-assurance-guide","Markdown Table Data Validation and Quality Assurance: Complete Guide for Content Integrity and Data Quality Management","Master advanced Markdown table data validation techniques for content integrity, quality assurance, and automated data verification. Learn validation rules, data quality checks, and error detection for professional documentation systems.","Advanced Markdown table data validation and quality assurance systems enable sophisticated content management workflows that ensure data integrity, maintain consistency standards, and provide…","2025-11-10","markdown table validation, data quality assurance, table content verification, markdown data integrity, table validation rules, content quality control, markdown table testing, data validation automation",31,{"slug":62,"title":63,"description":64,"excerpt":65,"date":66,"category":9,"author":10,"keywords":67,"readingMinutes":68},"markdown-table-data-validation-and-quality-assurance-complete-guide","Markdown Table Data Validation and Quality Assurance: Complete Guide for Automated Testing and Error Detection in Tabular Content","Master comprehensive data validation techniques for Markdown tables, implementing automated quality assurance, error detection systems, and data integrity checks for reliable tabular content management.","Advanced Markdown table data validation and quality assurance techniques enable systematic verification of tabular content accuracy, structural integrity, and formatting consistency across…","2025-12-18","markdown table validation, table data quality, automated table testing, markdown table errors, data validation markdown, table quality assurance, markdown table integrity, tabular data validation",26,1792184944513]