greenter/ubl-validator
Validate OASIS UBL XML documents against the correct XSD via UBLVersionID. Provide XML content, run isValid(), and get validation errors. Supports custom XSD base directories to validate multiple UBL versions (e.g., 2.1/2.2).
The greenter/ubl-validator package is a specialized, lightweight solution tailored for UBL XML schema validation, making it an ideal fit for Laravel-based applications requiring OASIS UBL compliance (v2.0/v2.1). Its modular design allows seamless integration into Laravel’s service-oriented architecture, enabling validation logic to be decoupled from controllers, jobs, or middleware. The package’s dependency-free nature (only PHP + LibXML) ensures minimal bloat and high compatibility with Laravel’s ecosystem.
Key architectural advantages:
files.stored) or queued jobs for async processing.Integration is low-risk and high-reward, with the following considerations:
UblPathResolver for custom schema versions.getError() in Laravel’s logging system or API error formats.| Risk Area | Mitigation Strategy |
|---|---|
| Schema Version Drift | Lock XSD versions in composer.json or implement a custom resolver to support future UBL versions (e.g., v2.2+ via forks). Monitor for package updates or forks. |
| XML Parsing Errors | Use try-catch blocks around isValid() to handle LibXML errors (e.g., LibXML::ERROR_NOELEMENT). Log errors for debugging and notify stakeholders of malformed inputs. |
| Performance Bottlenecks | For high-throughput systems, offload validation to Laravel Queues or background jobs. Cache validated schemas if reusing the same XSDs frequently. |
| False Positives/Negatives | Combine with business logic checks (e.g., currency validation, tax rules) to reduce false rejections. Test against real-world UBL samples (e.g., OASIS test cases). |
| Dependency Bloat | Audit composer require for transitive dependencies (e.g., symfony/process). Ensure no conflicts with Laravel’s existing stack (e.g., php-xml extensions). |
| Lack of v2.2+ Support | If v2.2+ is required, evaluate forking the package or using an alternative (e.g., UBL Validator by NIST). Alternatively, pre-process XML to conform to v2.1. |
UBL Version Requirements:
XML Source and Integration Points:
Error Handling and Workflows:
Scaling and Performance:
Testing and Compliance:
Future-Proofing:
The package integrates seamlessly with Laravel’s modular, event-driven architecture, offering multiple integration paths depending on use case:
| Integration Point | Use Case | Implementation Example |
|---|---|---|
| API Middleware | Validate XML payloads in real-time (e.g., /api/invoices). |
```php |
| public function handle(Request $request, Closure $next) { |
$validator = app(UblValidatorService::class);
if (!$validator->isValid($request->xml)) {
return response()->json(['error' => $validator->getError()], 400);
}
return $next($request);
}
| **File Uploads (Events)** | Validate UBL files **after upload** (e.g., `files.stored`). | ```php
public function handle() {
$path = event('files.stored')->path();
$xml = file_get_contents($path);
$validator = new UblValidator();
if (!$validator->isValid($xml)) {
Log::error("UBL validation failed: " . $validator->getError());
// Trigger cleanup or notification
}
}
``` |
| **Queue Jobs** | Process **large XML files asynchronously** (e.g., nightly batch validation). | ```php
class ValidateUblJob implements ShouldQueue {
public function handle() {
$xml = Storage::get('uploads/invoice.xml');
$validator = new UblValidator();
if (!$validator->isValid($xml)) {
ValidationFailed::dispatch($validator->getError());
}
}
}
``` |
| **Console Commands** | Run **ad-hoc validation** (e.g., `php artisan ubl:validate`). | ```php
public function handle() {
$files = Storage::disk('ubl')->files();
foreach ($files as $file) {
$xml = Storage::disk('ubl')->get($file);
$validator = new UblValidator();
$this->line($file . ($validator->isValid($xml) ? ' [OK]' : ' [FAILED]'));
}
}
``` |
| **Service Layer** | Reusable validation logic **injected into controllers/jobs**. | ```php
class InvoiceService {
public function __construct(private UblValidatorService $validator) {}
public function processInvoice(XmlPayload $payload) {
if (!$this->validator->isValid($payload->xml)) {
throw new InvalidInvoiceException($this->validator->getError());
}
// Proceed with business logic
}
}
``` |
### **Migration Path**
1. **Phase 1: Proof of Concept (1–2 Days)**
- Install the package: `composer require greenter/ubl-validator`.
- Test with **sample UBL XML** (e.g., from [OASIS](https://www.oasis-open.org/committees/ubl/)).
- Validate against **existing XML payloads** to ensure **no false positives/negatives**.
- **Decision Point**: Confirm UBL version compatibility and error handling requirements.
2. **Phase 2: Core Integration (3–5 Days)**
- **Option A (API)**: Add middleware to validate incoming XML requests.
- Create a `UblValidatorService` class to wrap the validator.
- Register middleware in `app/Http/Kernel.php`.
- **Option B
How can I help you explore Laravel packages today?