From 9a15b5ddca8eea1b4fb6cc150b69699a822d75aa Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Thu, 9 Oct 2025 21:53:53 +0000 Subject: [PATCH 1/3] This commit introduces a new documentation website built with Jekyll to improve the project's usability and accessibility. The key changes include: - A new `docs` directory configured to be served by GitHub Pages. - A Jekyll configuration file (`_config.yml`) with a minimal theme. - Core documentation pages for "Introduction" and "Architecture," including an SVG diagram. - A "Getting Started" tutorial that guides new users through cloning the repository and validating a sample XML file. - A structured `guides` section with placeholder pages for each ARCOS component, ready for content migration from the existing PDF documents. This new documentation site provides a modern, maintainable, and user-friendly platform for project information. --- docs/_config.yml | 3 + docs/architecture.md | 13 ++ docs/assets/ARCOS-Architecture.svg | 354 +++++++++++++++++++++++++++++ docs/getting-started.md | 65 ++++++ docs/guides.md | 12 + docs/guides/arcos-speculus.md | 12 + docs/guides/post-processor.md | 12 + docs/guides/producer.md | 12 + docs/guides/validator.md | 12 + docs/index.md | 15 ++ docs/introduction.md | 18 ++ 11 files changed, 528 insertions(+) create mode 100644 docs/_config.yml create mode 100644 docs/architecture.md create mode 100644 docs/assets/ARCOS-Architecture.svg create mode 100644 docs/getting-started.md create mode 100644 docs/guides.md create mode 100644 docs/guides/arcos-speculus.md create mode 100644 docs/guides/post-processor.md create mode 100644 docs/guides/producer.md create mode 100644 docs/guides/validator.md create mode 100644 docs/index.md create mode 100644 docs/introduction.md diff --git a/docs/_config.yml b/docs/_config.yml new file mode 100644 index 0000000..fce904e --- /dev/null +++ b/docs/_config.yml @@ -0,0 +1,3 @@ +theme: jekyll-theme-minimal +title: ARCOS Documentation +description: "Official documentation for the AI Rule-Constrained Orchestration System." \ No newline at end of file diff --git a/docs/architecture.md b/docs/architecture.md new file mode 100644 index 0000000..4df9dcc --- /dev/null +++ b/docs/architecture.md @@ -0,0 +1,13 @@ +--- +layout: default +title: Architecture +nav_order: 2 +--- + +# ARCOS Architecture + +The following diagram illustrates the high-level architecture of the ARCOS system. It shows the interaction between the **Maestro** coordinator and the various agents: **Speculus**, **Producer**, **Validator**, and **Post-Processor**. + +All communication between these components is handled via standardized XML messages, which are validated against the official ARCOS schemas. + +![ARCOS Architecture Diagram](./assets/ARCOS-Architecture.svg) \ No newline at end of file diff --git a/docs/assets/ARCOS-Architecture.svg b/docs/assets/ARCOS-Architecture.svg new file mode 100644 index 0000000..e1f065e --- /dev/null +++ b/docs/assets/ARCOS-Architecture.svg @@ -0,0 +1,354 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Page-1 + + + artefact_manifest.xsd + Artefact Manifest + + + + + Artefact Manifest + + Domain_Inputs + + + + Domain + + + + Domain_loop + + + + Producer + Producer + + Producer + + Validator + Validator + + Validator + + Post-Processor + Post-Processor + + Post-Processor + + ARCOS_Speculus + ARCOS-Speculus + + ARCOS-Speculus + + Domain_Speculus + Domain Speculus + + Domain Speculus + + Maestro_ARCOS_Speculus_Messaging.xsd + + + + + + ARCOS_Speculus_Response.xsd + + + + + + Maestro_Domain_Speculus_Messaging.xsd + + + + + + Domain_Speculus_Response.xsd + + + + + + Maestro_Producer_Messaging.xsd + + + + + + Producer_Response.xsd + + + + + + Maestro_Validator_Messaging.xsd + + + + + + Validator_Response.xsd + + + + + + Maestro_Post_Processor_Messaging.xsd + + + + + + Post_Processor_Response.xsd + + + + + + User + User + + User + + ARCOS_Speculus_User_Interactions + + + + Domain_Speculus_User_Interactions + + + + Maestro_User_Interactions + + + + ARCOS_Project.xsd + ARCOS_Project.XSD + + + + + ARCOS_Project.XSD + + ARCOS_Project.xml + ARCOS_Project.XML + + + + + ARCOS_Project.XML + + Domain_Rules.xsd + Domain_Rules.XSD + + + + + Domain_Rules.XSD + + Domain_Rules.xml + Domain_Rules.XML + + + + + Domain_Rules.XML + + Predefined_Domain_Rules.xsd + Pre Defined Domain Rules.XSD + + + + + Pre DefinedDomain Rules.XSD + + BLEU_Predefined_CRUD_Rules.xml + Pre Defined Domain Rules.XML + + + + + Pre DefinedDomain Rules.XML + + BLEU_parts_v5.xsd + Domain.XSD + + + + + Domain.XSD + + BLEU_inventory_v5_sample.xml + Inventory.XML + + + + + Inventory.XML + + Output.zip + Output.zip + + + + + + Output.zip + + Validator_Report.xml + Validator_Report.XML + + + + + Validator_Report.XML + + Validator_Report.xsd + Validator_Report.XSD + + + + + Validator_Report.XSD + + Post_Processor_Report.xml + Post_Processor_Report.XML + + + + + Post_Processor_Report.XML + + Post_Processor_Report.xsd + Post_Processor_Report.XSD + + + + + Post_Processor_Report.XSD + + Sheet.37 + Domain - Loop + + Domain - Loop + + Sheet.38 + Domain + + Domain + + Domain_Vocabulary.xsd + Domain_Vocabulary.xsd + + + + + Domain_Vocabulary.xsd + + Domain_Vocabulary.xml + Domain_Vocabulary.XML + + + + + Domain_Vocabulary.XML + + Focus Extractor + Focus Extractor + + FocusExtractor + + focus_manifest.xsd + Focus Manifest + + + + + Focus Manifest + + Artefact Extractor + Artefact Extractor + + ArtefactExtractor + + Orchestrator + Orchestrator + + Orchestrator + + \ No newline at end of file diff --git a/docs/getting-started.md b/docs/getting-started.md new file mode 100644 index 0000000..5e381ba --- /dev/null +++ b/docs/getting-started.md @@ -0,0 +1,65 @@ +--- +layout: default +title: Getting Started +nav_order: 4 +--- + +# Getting Started Tutorial + +This tutorial provides a hands-on walkthrough of the ARCOS repository. You will learn how to clone the project, locate key files, and perform a basic validation of a sample XML file against its schema. + +## Prerequisites + +Before you begin, ensure you have the following tools installed: +* **Git:** For cloning the repository. +* **An XML Schema Validator:** We will use `xmllint`, which is a standard command-line tool for XML validation, often pre-installed on Linux and macOS. + +## 1. Clone the Repository + +First, clone the ARCOS repository to your local machine using the following command: + +```bash +git clone https://github.com/ARCOS-System/ARCOS.git +cd ARCOS +``` + +## 2. Locate the Sample Files + +This repository includes sample domains to help you understand how ARCOS works. For this tutorial, we will use the `BLEU` sample domain. + +Navigate to the directory containing the sample XML and its corresponding schema: + +```bash +cd SampleDomains/BLEU/v5/ +``` + +You will find two key files here: +* `BLEU_parts_v5.xsd`: The XML Schema Definition (XSD) that defines the structure and rules for the inventory of a fictional parts manufacturer. +* `BLEU_inventory_v5_sample.xml`: A sample XML file containing inventory data that conforms to the schema. + +## 3. Understand the Schema and XML + +The **XSD file (`BLEU_parts_v5.xsd`)** acts as a blueprint, defining the expected structure of the data. It specifies what elements are allowed (e.g., `Bolt`, `Nut`, `Washer`), their attributes (e.g., `id`, `code`), and their data types. + +The **XML file (`BLEU_inventory_v5_sample.xml`)** is an instance of this blueprint. It contains the actual inventory data, structured according to the rules defined in the XSD. Notice the `xsi:noNamespaceSchemaLocation` attribute in the XML, which points to the location of the schema file that should be used for validation. + +## 4. Validate the XML + +The core principle of ARCOS is schema-driven validation. You can test this yourself by validating the sample XML against its schema using `xmllint`: + +```bash +xmllint --noout --schema BLEU_parts_v5.xsd BLEU_inventory_v5_sample.xml +``` + +If the validation is successful, the command will output: +``` +BLEU_inventory_v5_sample.xml validates +``` + +This confirms that the sample data adheres to the rules defined in the schema. + +## Conclusion + +Congratulations! You have successfully cloned the ARCOS repository and validated a sample XML file. This simple exercise demonstrates the fundamental concept of ARCOS: ensuring that all data and messages conform to a predefined, verifiable structure. + +From here, you can explore the other documentation sections to learn more about the system's [Architecture](./architecture.md) and [Component Guides](./guides.md). \ No newline at end of file diff --git a/docs/guides.md b/docs/guides.md new file mode 100644 index 0000000..07dabd8 --- /dev/null +++ b/docs/guides.md @@ -0,0 +1,12 @@ +--- +layout: default +title: Guides +nav_order: 3 +has_children: true +--- + +# Component Guides + +This section provides detailed guides for each of the major components in the ARCOS system. + +Select a guide from the navigation menu to learn more about a specific component. \ No newline at end of file diff --git a/docs/guides/arcos-speculus.md b/docs/guides/arcos-speculus.md new file mode 100644 index 0000000..4b49c35 --- /dev/null +++ b/docs/guides/arcos-speculus.md @@ -0,0 +1,12 @@ +--- +layout: default +title: ARCOS Speculus Guide +parent: Guides +nav_order: 1 +--- + +# ARCOS Speculus Guide + +*This guide provides a detailed overview of the ARCOS Speculus component.* + +**(Content to be migrated from `3-Domain and ARCOS_Speculus_Guide.pdf`)** \ No newline at end of file diff --git a/docs/guides/post-processor.md b/docs/guides/post-processor.md new file mode 100644 index 0000000..8bd0b1a --- /dev/null +++ b/docs/guides/post-processor.md @@ -0,0 +1,12 @@ +--- +layout: default +title: Domain Post-Processor Guide +parent: Guides +nav_order: 4 +--- + +# Domain Post-Processor Guide + +*This guide provides a detailed overview of the Domain Post-Processor component.* + +**(Content to be migrated from `6-Domain_Post-Processor_Guide.pdf`)** \ No newline at end of file diff --git a/docs/guides/producer.md b/docs/guides/producer.md new file mode 100644 index 0000000..c381c8d --- /dev/null +++ b/docs/guides/producer.md @@ -0,0 +1,12 @@ +--- +layout: default +title: Domain Producer Guide +parent: Guides +nav_order: 2 +--- + +# Domain Producer Guide + +*This guide provides a detailed overview of the Domain Producer component.* + +**(Content to be migrated from `4-Domain_Producer_Guide.pdf`)** \ No newline at end of file diff --git a/docs/guides/validator.md b/docs/guides/validator.md new file mode 100644 index 0000000..cb6922b --- /dev/null +++ b/docs/guides/validator.md @@ -0,0 +1,12 @@ +--- +layout: default +title: Domain Validator Guide +parent: Guides +nav_order: 3 +--- + +# Domain Validator Guide + +*This guide provides a detailed overview of the Domain Validator component.* + +**(Content to be migrated from `5-Domain_Validator_Guide.pdf`)** \ No newline at end of file diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 0000000..13cfdb8 --- /dev/null +++ b/docs/index.md @@ -0,0 +1,15 @@ +--- +layout: default +title: Home +nav_order: 1 +--- + +# Welcome to ARCOS Documentation + +**ARCOS** is a schema-driven framework for orchestrating AI agents under strict specification and validation rules. + +This site provides the official documentation for the ARCOS project. Use the navigation to explore the different components and concepts. + +## Getting Started + +To get started, check out the [Getting Started](./getting-started.md) page. \ No newline at end of file diff --git a/docs/introduction.md b/docs/introduction.md new file mode 100644 index 0000000..a900d32 --- /dev/null +++ b/docs/introduction.md @@ -0,0 +1,18 @@ +--- +layout: default +title: Introduction +nav_order: 1 +--- + +# Introduction to ARCOS + +**ARCOS (AI Rule-Constrained Orchestration System)** is a schema-driven framework for orchestrating AI agents under strict specification and validation rules. It defines how a Coordinator (**Maestro**) interacts with **Speculus**, **Producer**, **Validator**, and **Post-Processor** agents through domain-agnostic XML messaging validated against schemas. + +## Why ARCOS? + +- **Deterministic AI orchestration**: Every interaction is validated against XSD contracts. +- **Composable agents**: Swap in your own Producers, Validators, or Post-Processors. +- **Domain-agnostic**: Bring your own schema; ARCOS will give it to each domain component. +- **Fail-fast philosophy**: Invalid XML is rejected immediately. + +This documentation site will guide you through the core concepts, architecture, and components of the ARCOS system. \ No newline at end of file From 19c162dd627878016275b4becf1e38586adaaa7d Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Thu, 9 Oct 2025 22:13:29 +0000 Subject: [PATCH 2/3] This commit enhances the project by adding a CI validation workflow and a new documentation website. Key changes: - **CI for XML Validation:** - A new GitHub Actions workflow (`validate-xml.yml`) has been added. - On every push, this workflow automatically validates all sample XML files in `SampleDomains/` against their corresponding XSD schemas using `xmllint`. - This ensures the integrity and correctness of all examples. - **Jekyll-based Documentation Website:** - A new `docs/` directory configured to be served by GitHub Pages. - Core documentation pages for "Introduction" and "Architecture". - A "Getting Started" tutorial for new users. - A structured `guides` section with placeholders for component documentation. These changes improve project maintainability and provide a modern, user-friendly platform for documentation. --- .github/workflows/validate-xml.yml | 50 ++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 .github/workflows/validate-xml.yml diff --git a/.github/workflows/validate-xml.yml b/.github/workflows/validate-xml.yml new file mode 100644 index 0000000..f107f90 --- /dev/null +++ b/.github/workflows/validate-xml.yml @@ -0,0 +1,50 @@ +name: Validate XML Samples + +on: + push: + branches: [ main ] + pull_request: + branches: [ main ] + +jobs: + validate-xml: + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Install libxml2-utils + run: sudo apt-get update && sudo apt-get install -y libxml2-utils + + - name: Validate XML against local XSD + run: | + find SampleDomains -type f -name "*.xml" | while read xml_file; do + echo "INFO: Processing '$xml_file'" + + # Extract the schema URL from the XML file + schema_url=$(grep -o 'xsi:noNamespaceSchemaLocation="[^"]*"' "$xml_file" | cut -d'"' -f2) + + if [ -z "$schema_url" ]; then + echo "WARN: No schemaLocation found in '$xml_file'. Skipping." + continue + fi + + # Convert the GitHub raw URL to a local file path. + # This handles different branch names in the URL. + schema_file=$(echo "$schema_url" | sed 's|https://raw.githubusercontent.com/ARCOS-System/ARCOS/[^/]\+/\(.*\)|\1|') + + if [ ! -f "$schema_file" ]; then + echo "ERROR: Could not find local schema file '$schema_file' referenced in '$xml_file'. Failing the check." + exit 1 + fi + + echo "INFO: Validating '$xml_file' against '$schema_file'..." + if xmllint --noout --schema "$schema_file" "$xml_file"; then + echo "SUCCESS: '$xml_file' is valid." + else + echo "ERROR: Validation of '$xml_file' failed." + exit 1 + fi + echo "" + done \ No newline at end of file From ae9d4db971ef8cb3dafd26271c8ac76b7af0c934 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Thu, 9 Oct 2025 22:25:31 +0000 Subject: [PATCH 3/3] This commit introduces the foundational structure for a Python-based reference implementation of the ARCOS system. This initial implementation includes: - A new `src/arcos` directory for the Python package. - A `requirements.txt` file with `lxml` as a dependency. - A core XML utility module (`xml_utils.py`) with a robust `validate_xml` function that correctly handles namespace differences. - Abstract base classes for all ARCOS agents (`agents.py`) to define a standard interface. - A basic placeholder implementation of the `Maestro` orchestrator (`maestro.py`). - A sample `BleuProducer` (`producers.py`) that demonstrates a concrete agent implementation for the BLEU domain. - A `tests` directory with a permanent unit test for the `xml_utils` module to ensure its long-term stability. --- requirements.txt | 1 + src/arcos/__init__.py | 1 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 123 bytes .../__pycache__/xml_utils.cpython-312.pyc | Bin 0 -> 3310 bytes src/arcos/agents.py | 82 ++++++++++++++++++ src/arcos/maestro.py | 31 +++++++ src/arcos/producers.py | 35 ++++++++ src/arcos/xml_utils.py | 67 ++++++++++++++ .../test_xml_utils.cpython-312.pyc | Bin 0 -> 2358 bytes tests/test_xml_utils.py | 33 +++++++ 10 files changed, 250 insertions(+) create mode 100644 requirements.txt create mode 100644 src/arcos/__init__.py create mode 100644 src/arcos/__pycache__/__init__.cpython-312.pyc create mode 100644 src/arcos/__pycache__/xml_utils.cpython-312.pyc create mode 100644 src/arcos/agents.py create mode 100644 src/arcos/maestro.py create mode 100644 src/arcos/producers.py create mode 100644 src/arcos/xml_utils.py create mode 100644 tests/__pycache__/test_xml_utils.cpython-312.pyc create mode 100644 tests/test_xml_utils.py diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..fcba197 --- /dev/null +++ b/requirements.txt @@ -0,0 +1 @@ +lxml~=5.2.0 \ No newline at end of file diff --git a/src/arcos/__init__.py b/src/arcos/__init__.py new file mode 100644 index 0000000..7f016be --- /dev/null +++ b/src/arcos/__init__.py @@ -0,0 +1 @@ +# This file marks the 'arcos' directory as a Python package. \ No newline at end of file diff --git a/src/arcos/__pycache__/__init__.cpython-312.pyc b/src/arcos/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ff483793231133ae98d113c5377821995ff60ea8 GIT binary patch literal 123 zcmX@j%ge<81gvH+GHihKV-N=&d}aZPOlPQM&}8&m$xy@uFSWuu}T$HSz xSd^S!tREkrnU`4-AFo$Xd5gm)H$SB`C)KWq6{wUEh>JmtkIamWj77{q766h#86N-u literal 0 HcmV?d00001 diff --git a/src/arcos/__pycache__/xml_utils.cpython-312.pyc b/src/arcos/__pycache__/xml_utils.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..51b7e18bf7e3fcb0ad991fb895a1a35ec5a413e1 GIT binary patch literal 3310 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 str: + """ + Generates an artifact based on the provided specification. + + Args: + spec: A dictionary representing the production specification. + + Returns: + A string representing the generated artifact (e.g., XML content). + """ + pass + +class Validator(ABC): + """ + Abstract base class for a Validator agent. + + A Validator checks if a given artifact conforms to a set of rules or a schema. + """ + + @abstractmethod + def validate(self, artifact_path: str, rules_path: str) -> bool: + """ + Validates an artifact against a set of rules. + + Args: + artifact_path: The path to the artifact to be validated. + rules_path: The path to the rules or schema to validate against. + + Returns: + True if the artifact is valid, False otherwise. + """ + pass + +class PostProcessor(ABC): + """ + Abstract base class for a Post-Processor agent. + + A Post-Processor performs some action on a validated artifact, such as + transformation, enrichment, or reporting. + """ + + @abstractmethod + def process(self, artifact_path: str) -> str: + """ + Processes a validated artifact. + + Args: + artifact_path: The path to the validated artifact. + + Returns: + A string representing the result of the post-processing. + """ + pass \ No newline at end of file diff --git a/src/arcos/maestro.py b/src/arcos/maestro.py new file mode 100644 index 0000000..a8c0921 --- /dev/null +++ b/src/arcos/maestro.py @@ -0,0 +1,31 @@ +from .agents import Maestro, Producer, Validator, PostProcessor + +class BasicMaestro(Maestro): + """ + A basic implementation of the Maestro orchestrator. + + This implementation provides a simple, linear workflow for demonstration. + """ + def __init__(self, producer: Producer, validator: Validator, post_processor: PostProcessor): + self.producer = producer + self.validator = validator + self.post_processor = post_processor + + def orchestrate(self, spec_path: str, output_path: str): + """ + A placeholder for the orchestration logic. + + In a real implementation, this would involve: + 1. Reading and parsing the spec. + 2. Calling the producer. + 3. Calling the validator on the produced artifact. + 4. Calling the post-processor on the validated artifact. + 5. Writing the final result to the output path. + """ + print("--- BasicMaestro: Orchestration process started. ---") + print(f" - Specification file: {spec_path}") + print(f" - Producer: {self.producer.__class__.__name__}") + print(f" - Validator: {self.validator.__class__.__name__}") + print(f" - Post-Processor: {self.post_processor.__class__.__name__}") + print(f" - Final output will be at: {output_path}") + print("--- Orchestration logic is not yet implemented. ---") \ No newline at end of file diff --git a/src/arcos/producers.py b/src/arcos/producers.py new file mode 100644 index 0000000..fcda264 --- /dev/null +++ b/src/arcos/producers.py @@ -0,0 +1,35 @@ +from .agents import Producer + +class BleuProducer(Producer): + """ + A sample Producer for the BLEU parts inventory domain. + + This producer generates a sample XML artifact based on a predefined + template file. + """ + + def __init__(self, template_path: str): + """ + Initializes the producer with a path to a template XML file. + + Args: + template_path: The path to the sample XML file to use as a template. + """ + self.template_path = template_path + + def produce(self, spec: dict) -> str: + """ + "Produces" an XML artifact by reading it from a template file. + + In a real implementation, this method would dynamically generate + the XML based on the content of the `spec` dictionary. + + Args: + spec: A dictionary representing the production specification (unused in this sample). + + Returns: + A string containing the content of the template XML file. + """ + print(f"--- BleuProducer: 'Producing' artifact from template: {self.template_path} ---") + with open(self.template_path, 'r', encoding='utf-8') as f: + return f.read() \ No newline at end of file diff --git a/src/arcos/xml_utils.py b/src/arcos/xml_utils.py new file mode 100644 index 0000000..dabfdbd --- /dev/null +++ b/src/arcos/xml_utils.py @@ -0,0 +1,67 @@ +from lxml import etree + +def _add_namespace_to_tree(element, namespace): + """ + Recursively adds a namespace to an element and all its children. + This is for validating a no-namespace XML against a schema with a targetNamespace. + """ + element.tag = f"{{{namespace}}}{etree.QName(element).localname}" + for child in element: + _add_namespace_to_tree(child, namespace) + +def validate_xml(xml_path: str, xsd_path: str) -> bool: + """ + Validates an XML file against an XSD schema. + + This function handles the case where the XML file has no namespace but the + schema defines a targetNamespace by adding the namespace to the XML tree + in memory before validation. + + Args: + xml_path: The path to the XML file to validate. + xsd_path: The path to the XSD schema file. + + Returns: + True if the XML is valid against the schema. + + Raises: + etree.XMLSyntaxError: If the XML or XSD file is not well-formed. + etree.DocumentInvalid: If the XML document is not valid against the schema. + """ + try: + # Parse the XSD schema and get its target namespace from the root element + with open(xsd_path, 'rb') as f: + schema_doc = etree.parse(f) + target_namespace = schema_doc.getroot().get('targetNamespace') + + # Compile the schema + schema = etree.XMLSchema(schema_doc) + + # Parse the XML file + with open(xml_path, 'rb') as f: + xml_doc = etree.parse(f) + + root = xml_doc.getroot() + + # If the root element has no namespace, assume it should be in the schema's target namespace. + if etree.QName(root).namespace is None and target_namespace: + _add_namespace_to_tree(root, target_namespace) + + # Validate the (potentially modified) XML against the schema + schema.assertValid(xml_doc) + + print(f"SUCCESS: '{xml_path}' is valid against '{xsd_path}'.") + return True + + except etree.XMLSyntaxError as e: + print(f"ERROR: XML or XSD syntax error in '{xml_path}' or '{xsd_path}'.") + raise e + except etree.DocumentInvalid as e: + print(f"ERROR: XML document '{xml_path}' is invalid against schema '{xsd_path}'.") + # Print the detailed validation errors for better debugging + for error in schema.error_log: + print(f" - Line {error.line}, Column {error.column}: {error.message}") + raise e + except Exception as e: + print(f"ERROR: An unexpected error occurred during validation.") + raise e \ No newline at end of file diff --git a/tests/__pycache__/test_xml_utils.cpython-312.pyc b/tests/__pycache__/test_xml_utils.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8461e32b94a0678f889de73a429f412b9949c07c GIT binary patch literal 2358 zcma)7O>7fK6rR~1dojBSNhnQ#!lD|e1-46t0jV@7g%(l)l^{sq%WCW02&ZeWJF`w= zi%L{VRU%air-lOuPE}Empr^K{igPb@8)USARH;3*w}>EB;?(!{$4=5fJC@(RnR)YO z=6m0J^OL5f2sHW7pO^1Sg#3=3xXF>SJOj!+v4}+-QVhSeNTDw{LPac!6vsqIs>nr| z5`ml~mNY{w*(MWe?5z7;5JSC~v=uAy@f(D&eu02(f7d3~79xd`25rzx@-OV4%}`&R zG@Y_#dbTlLaiA~T9<%LIybixK>MW;0nTHMV$VI`TGo&b50!YacLCSd8Vxl2u623ZS zbMIosx!{!@UWz@SqXhi%;LBfw05IqkVt^JlOMqU-+7h8B#B*LU)~=8VfOu`Qq=m?~ zKt82c=){J#76hPNh`a;T3H-%t0GPz<__Q4@PQ*3!hFkdybBVJI-B`7L{!e2S=_+UusJUvg>Uec z0~xl74s+rWLMGx=><$rN6LNA*i+RFyufxX)yw{rc^3_qg3C*G7j%`*$232YHfnQ+XAjQ}&ko;6x3}h7Tl0$>-+Zk0%#F^DUbos?_O-U`d!X)L5{Y_X8J3V$ z@OIMmBbb>-usU#{ZP+{vK+x7t%@=?a1t^9Z!O95DEZ#`>E}Nci>H(Mai)T&;XhFVl z4yhN_tg>4L_#{7tqs$v)b(`Ty7-l}hddyx0u@bnUfX31KpynC8UMks~H}|YT66n63 zUEpyixCL%2>Rj(^?@jgASbO)8*6t(Ur+>`;ko|S=)B|Od4S~)2P~L%=7ed)#?RqsX zhN=M7X;nR3pP9jv1e>jB-FjzH{B`>c`mg#&qxvT_kF5wwRgdaOH!jR9V_Z(SrFsRb zT~w2Fd%9%Tyf94gCWK)+7uYha;C}C#6=C?0{Qo4Y<^53e+cVmk^Q#BCB#BuHq6X%+}n zIC5-;Je3rA&(qDKoPC-SqpuH>DEB{8G+8yK_aQwn!kuc52e1Vr@lDz*_qEjgi0fA4cz|& Dgp(4x literal 0 HcmV?d00001 diff --git a/tests/test_xml_utils.py b/tests/test_xml_utils.py new file mode 100644 index 0000000..9d00144 --- /dev/null +++ b/tests/test_xml_utils.py @@ -0,0 +1,33 @@ +import unittest +import os +from src.arcos.xml_utils import validate_xml +from lxml import etree + +class TestXmlUtils(unittest.TestCase): + + def setUp(self): + """Set up test files and paths.""" + self.valid_xml_path = "SampleDomains/BLEU/v5/BLEU_inventory_v5_sample.xml" + self.xsd_path = "SampleDomains/BLEU/v5/BLEU_parts_v5.xsd" + + # Create a temporary invalid XML file for testing failure cases + self.invalid_xml_path = "tests/invalid_sample.xml" + with open(self.invalid_xml_path, "w") as f: + f.write("") + + def tearDown(self): + """Clean up temporary files.""" + if os.path.exists(self.invalid_xml_path): + os.remove(self.invalid_xml_path) + + def test_validate_xml_success(self): + """Test that a valid XML file passes validation.""" + self.assertTrue(validate_xml(self.valid_xml_path, self.xsd_path)) + + def test_validate_xml_failure(self): + """Test that an invalid XML file raises DocumentInvalid exception.""" + with self.assertRaises(etree.DocumentInvalid): + validate_xml(self.invalid_xml_path, self.xsd_path) + +if __name__ == '__main__': + unittest.main() \ No newline at end of file