Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Ubl Validator Laravel Package

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).

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation:

    composer require greenter/ubl-validator
    
  2. Basic Validation:

    use Greenter\Ubl\UblValidator;
    
    $xml = file_get_contents('invoice.xml');
    $validator = new UblValidator();
    
    if ($validator->isValid($xml)) {
        // Proceed with business logic
    } else {
        $error = $validator->getError();
        // Log or return error to user
    }
    
  3. First Use Case: Validate an incoming UBL invoice XML in a Laravel API endpoint:

    use Greenter\Ubl\UblValidator;
    
    public function store(Request $request) {
        $validator = new UblValidator();
        if (!$validator->isValid($request->xml)) {
            return response()->json(['error' => $validator->getError()], 400);
        }
        // Process valid invoice
    }
    

Where to Look First

  • Package Source: GitHub Repository
  • Key Classes:
    • UblValidator: Core validation logic.
    • UblPathResolver: Custom XSD directory configuration.
  • XSD Files: Located in src/xsd (default) or configurable via baseDirectory.

Implementation Patterns

Usage Patterns

  1. API Request Validation:

    public function validateInvoice(Request $request) {
        $ublValidator = app()->make(UblValidator::class);
        if (!$ublValidator->isValid($request->xml)) {
            return response()->json(['error' => $ublValidator->getError()], 400);
        }
        return response()->json(['success' => true]);
    }
    
  2. File Upload Validation:

    use Illuminate\Support\Facades\Storage;
    use Greenter\Ubl\UblValidator;
    
    public function handleUpload(Request $request) {
        $file = $request->file('invoice');
        $xml = file_get_contents($file->path());
        $validator = new UblValidator();
    
        if (!$validator->isValid($xml)) {
            Storage::delete($file->path());
            return back()->withErrors(['invoice' => $validator->getError()]);
        }
        // Save file and proceed
    }
    
  3. Batch Processing with Queues:

    use Greenter\Ubl\UblValidator;
    use Illuminate\Bus\Queueable;
    use Illuminate\Queue\SerializesModels;
    use Illuminate\Queue\InteractsWithQueue;
    use Illuminate\Contracts\Queue\ShouldQueue;
    
    class ValidateUblJob implements ShouldQueue {
        use InteractsWithQueue, Queueable, SerializesModels;
    
        public $xml;
    
        public function __construct($xml) {
            $this->xml = $xml;
        }
    
        public function handle() {
            $validator = new UblValidator();
            if (!$validator->isValid($this->xml)) {
                // Log error or notify
            }
        }
    }
    
  4. Custom XSD Directory:

    $validator = new UblValidator();
    $validator->pathResolver = new UblPathResolver();
    $validator->pathResolver->baseDirectory = storage_path('app/xsd/ubl');
    

Workflows

  1. Supplier Onboarding:

    • Validate UBL invoices during supplier registration.
    • Store validation results in a supplier_validations table.
  2. E-Invoicing Compliance:

    • Integrate with tax authority APIs after validation.
    • Example:
      if ($validator->isValid($invoiceXml)) {
          $taxAuthorityResponse = TaxAuthority::submit($invoiceXml);
      }
      
  3. Data Migration:

    • Validate legacy UBL files during ERP migration.
    • Example:
      $files = Storage::disk('legacy')->files('invoices');
      foreach ($files as $file) {
          $xml = file_get_contents($file);
          $validator->isValid($xml) ? $this->migrate($file) : $this->logError($file);
      }
      

Integration Tips

  1. Laravel Service Provider: Bind UblValidator to the container for dependency injection:

    public function register() {
        $this->app->bind(UblValidator::class, function () {
            return new UblValidator();
        });
    }
    
  2. Middleware for API Protection:

    public function handle($request, Closure $next) {
        $validator = new UblValidator();
        if (!$validator->isValid($request->xml)) {
            return response()->json(['error' => $validator->getError()], 400);
        }
        return $next($request);
    }
    
  3. Logging Errors:

    use Illuminate\Support\Facades\Log;
    
    if (!$validator->isValid($xml)) {
        Log::error('UBL Validation Failed: ' . $validator->getError());
    }
    
  4. Testing: Use Laravel’s testing helpers to mock XML responses:

    public function testUblValidation() {
        $xml = file_get_contents(__DIR__ . '/fixtures/invoice.xml');
        $validator = new UblValidator();
        $this->assertTrue($validator->isValid($xml));
    }
    

Gotchas and Tips

Pitfalls

  1. XSD Directory Structure:

    • The package expects a specific directory structure for custom XSDs:
      /my-ubl-xsd
      ├── 2.1/
      │   ├── common/
      │   └── maindoc/
      └── 2.2/
          ├── common/
          └── maindoc/
      
    • Fix: Ensure your custom XSD directory matches this structure or modify the resolver logic.
  2. XML Parsing Errors:

    • Malformed XML (e.g., missing root element) may throw LibXML exceptions.
    • Solution: Wrap validation in a try-catch:
      try {
          if (!$validator->isValid($xml)) {
              // Handle validation error
          }
      } catch (\Exception $e) {
          Log::error('XML Parsing Error: ' . $e->getMessage());
      }
      
  3. Version Mismatch:

    • The package supports UBL v2.0, v2.1, and v2.2 (as of last release).
    • Gotcha: If your XML uses a newer version (e.g., v2.3), validation will fail.
    • Solution: Use a custom XSD directory with the correct schemas or wait for an update.
  4. Performance with Large XML:

    • Validating large XML files (e.g., >10MB) may cause timeouts or memory issues.
    • Solution: Use Laravel Queues for async validation or optimize XML parsing.
  5. Error Handling:

    • The package returns raw error messages, which may not be user-friendly.
    • Solution: Create a wrapper class to format errors:
      class UblValidationError {
          public static function format(string $error): string {
              return "Invalid UBL XML: " . substr($error, 0, 200) . "...";
          }
      }
      

Debugging

  1. Enable LibXML Errors:

    libxml_use_internal_errors(true);
    $validator->isValid($xml);
    $errors = libxml_get_errors();
    foreach ($errors as $error) {
        echo "Error: " . $error->message . "\n";
    }
    libxml_clear_errors();
    
  2. Check XSD Resolution:

    • If validation fails unexpectedly, verify the correct XSD is being loaded:
      $validator = new UblValidator();
      $validator->pathResolver = new UblPathResolver();
      $validator->pathResolver->baseDirectory = './custom-xsd';
      
  3. Validate Against Known Good XML:

    • Test with sample UBL XML from OASIS to ensure the package works as expected.

Config Quirks

  1. Default XSD Directory:

    • The package includes default XSDs in src/xsd, but these may not cover all UBL versions.
    • Tip: Always verify which versions are supported in the composer.json or release notes.
  2. Case Sensitivity:

    • UBL XML is case-sensitive. Ensure your XML matches the schema exactly (e.g., <cbc:UBLVersionID> vs. <CBC:UBLVersionID>).
  3. Namespace Handling:

    • The validator expects XML namespaces to be correctly declared. Missing or incorrect namespaces will cause validation to fail.
    • Example:
      <Invoice xmlns="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2" ...>
      

Extension Points

  1. Custom Error Formatting:
    • Extend the UblValidator class to add custom error handling:
      class CustomUblValidator extends UblValidator {
          public function getFormattedError(): string {
              $error = $this->getError();
              return "Validation Failed
      
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
terminal42/code-quality-tools
codifyo/ts-generator-bundle
andydefer/laravel-cluster
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky