phpxmlsymfonysymfony2

Symfony2: "Invalid Schema" in CRUD edit view


We have a site that is running version 2.0.17 of Symfony (yes, we know it's obsolete, migration to 2.2.x is underway). It has worked fine until a few days ago, when we started to get an error 500 with this message:

Warning: DOMDocument::schemaValidate(): Invalid Schema in /var/www/customers/customername/symfony/vendor/symfony/src/Symfony/Component/Validator/Mapping/Loader/XmlFileLoader.php line 197

The error happens when we try to create an edit form with FormBuilder. Everything works fine in our dev and test environments, which makes it a huge pain to troubleshoot.

What could be the possible causes of this problem? No new changes to the site have been pushed since January and it has definitely worked in the beginning of March as that is the timestamp on the newest published content.

Here's the relevant part of a full stack trace. DOMDocument->schemaValidate() is the method that causes the warning.

at DOMDocument ->schemaValidate ('/var/www/customers/customername/symfony/vendor/symfony/src/Symfony/Component/Validator/Mapping/Loader/schema/dic/constraint-mapping/constraint-mapping-1.0.xsd') 
  in /var/www/customers/customername/symfony/vendor/symfony/src/Symfony/Component/Validator/Mapping/Loader/XmlFileLoader.php at line 197    
at XmlFileLoader ->parseFile ('/var/www/customers/customername/symfony/vendor/symfony/src/Symfony/Component/Form/Resources/config/validation.xml') 
  in /var/www/customers/customername/symfony/vendor/symfony/src/Symfony/Component/Validator/Mapping/Loader/XmlFileLoader.php at line 32    
at XmlFileLoader ->loadClassMetadata (object(ClassMetadata)) 
  in /var/www/customers/customername/symfony/vendor/symfony/src/Symfony/Component/Validator/Mapping/Loader/LoaderChain.php at line 57    
at LoaderChain ->loadClassMetadata (object(ClassMetadata)) 
  in /var/www/customers/customername/symfony/vendor/symfony/src/Symfony/Component/Validator/Mapping/Loader/LoaderChain.php at line 57    
at LoaderChain ->loadClassMetadata (object(ClassMetadata)) 
  in /var/www/customers/customername/symfony/vendor/symfony/src/Symfony/Component/Validator/Mapping/ClassMetadataFactory.php at line 68    
at ClassMetadataFactory ->getClassMetadata ('OurCompany\OurCMSBundle\SearchableInterface') 
  in /var/www/customers/customername/symfony/vendor/symfony/src/Symfony/Component/Validator/Mapping/ClassMetadataFactory.php at line 65    
at ClassMetadataFactory ->getClassMetadata ('OurCompany\OurCMSBundle\Entity\News') 
  in /var/www/customers/customername/symfony/vendor/symfony/src/Symfony/Component/Form/Extension/Validator/ValidatorTypeGuesser.php at line 314    
at ValidatorTypeGuesser ->guess ('OurCompany\OurCMSBundle\Entity\News', 'title', object(Closure)) 
  in /var/www/customers/customername/symfony/vendor/symfony/src/Symfony/Component/Form/Extension/Validator/ValidatorTypeGuesser.php at line 39    
at ValidatorTypeGuesser ->guessType ('OurCompany\OurCMSBundle\Entity\News', 'title') 
  in /var/www/customers/customername/symfony/vendor/symfony/src/Symfony/Component/Form/FormTypeGuesserChain.php at line 46    
at Symfony\Component\Form\{closure} (object(ValidatorTypeGuesser)) 
  in /var/www/customers/customername/symfony/vendor/symfony/src/Symfony/Component/Form/FormTypeGuesserChain.php at line 85    
at FormTypeGuesserChain ->guess (object(Closure)) 
  in /var/www/customers/customername/symfony/vendor/symfony/src/Symfony/Component/Form/FormTypeGuesserChain.php at line 47    
at FormTypeGuesserChain ->guessType ('OurCompany\OurCMSBundle\Entity\News', 'title') 
  in /var/www/customers/customername/symfony/vendor/symfony/src/Symfony/Component/Form/FormFactory.php at line 315    
at FormFactory ->createBuilderForProperty ('OurCompany\OurCMSBundle\Entity\News', 'title', null, array()) 
  in /var/www/customers/customername/symfony/vendor/symfony/src/Symfony/Component/Form/FormBuilder.php at line 575    
at FormBuilder ->create ('title', null, array()) 
  in /var/www/customers/customername/symfony/vendor/symfony/src/Symfony/Component/Form/FormBuilder.php at line 691    
at FormBuilder ->buildChildren () 
  in /var/www/customers/customername/symfony/vendor/symfony/src/Symfony/Component/Form/FormBuilder.php at line 654    
at FormBuilder ->getForm () 
  in /var/www/customers/customername/symfony/vendor/symfony/src/Symfony/Component/Form/FormFactory.php at line 138    
at FormFactory ->create (object(NewsType), object(News), array()) 
  in /var/www/customers/customername/symfony/vendor/symfony/src/Symfony/Bundle/FrameworkBundle/Controller/Controller.php at line 129   
at Controller ->createForm (object(NewsType), object(News)) 
  in /var/www/customers/customername/symfony/src/Customer/OurCMSBundle/Controller/NewsController.php at line 127    
at NewsController ->editAction ('2') 

The schema that is used is part of the Symfony Validator component, located in vendor/symfony/src/Symfony/Component/Validator/Mapping/Loader/schema/dic/constraint-mapping/constraint-mapping-1.0.xsd. It validates when checked with the w3.org validator. Here is the schema:

<?xml version="1.0" ?>

<xsd:schema xmlns="http://symfony.com/schema/dic/constraint-mapping"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    targetNamespace="http://symfony.com/schema/dic/constraint-mapping"
    elementFormDefault="qualified">

  <xsd:annotation>
    <xsd:documentation><![CDATA[
      Symfony Validator Constraint Mapping Schema, version 1.0
      Authors: Bernhard Schussek

      A constraint mapping connects classes, properties and getters with
      validation constraints.
    ]]></xsd:documentation>
  </xsd:annotation>

  <xsd:element name="constraint-mapping" type="constraint-mapping" />

  <xsd:complexType name="constraint-mapping">
    <xsd:annotation>
      <xsd:documentation><![CDATA[
        The root element of the constraint mapping definition.
      ]]></xsd:documentation>
    </xsd:annotation>
    <xsd:sequence>
      <xsd:element name="namespace" type="namespace" minOccurs="0" maxOccurs="unbounded" />
      <xsd:element name="class" type="class" maxOccurs="unbounded" />
    </xsd:sequence>
  </xsd:complexType>

  <xsd:complexType name="namespace">
    <xsd:annotation>
      <xsd:documentation><![CDATA[
        Contains the abbreviation for a namespace.
      ]]></xsd:documentation>
    </xsd:annotation>
    <xsd:simpleContent>
      <xsd:extension base="xsd:string">
        <xsd:attribute name="prefix" type="xsd:string" use="required" />
      </xsd:extension>
    </xsd:simpleContent>
  </xsd:complexType>

  <xsd:complexType name="class">
    <xsd:annotation>
      <xsd:documentation><![CDATA[
        Contains constraints for a single class.

        Nested elements may be class constraints, property and/or getter
        definitions.
      ]]></xsd:documentation>
    </xsd:annotation>
    <xsd:choice minOccurs="0" maxOccurs="unbounded">
      <xsd:element name="group-sequence" type="group-sequence" minOccurs="0" maxOccurs="1" />
      <xsd:element name="constraint" type="constraint" minOccurs="0" maxOccurs="unbounded" />
      <xsd:element name="property" type="property" minOccurs="0" maxOccurs="unbounded" />
      <xsd:element name="getter" type="getter" minOccurs="0" maxOccurs="unbounded" />
    </xsd:choice>
    <xsd:attribute name="name" type="xsd:string" use="required" />
  </xsd:complexType>

  <xsd:complexType name="group-sequence">
    <xsd:annotation>
      <xsd:documentation><![CDATA[
        Contains the group sequence of a class. Each group should be written
        into a "value" tag.
      ]]></xsd:documentation>
    </xsd:annotation>
    <xsd:sequence>
      <xsd:element name="value" type="value" minOccurs="1" maxOccurs="unbounded" />
    </xsd:sequence>
  </xsd:complexType>

  <xsd:complexType name="property">
    <xsd:annotation>
      <xsd:documentation><![CDATA[
        Contains constraints for a single property. The name of the property
        should be given in the "name" option.
      ]]></xsd:documentation>
    </xsd:annotation>
    <xsd:sequence>
      <xsd:element name="constraint" type="constraint" maxOccurs="unbounded" />
    </xsd:sequence>
    <xsd:attribute name="name" type="xsd:string" use="required" />
  </xsd:complexType>

  <xsd:complexType name="getter">
    <xsd:annotation>
      <xsd:documentation><![CDATA[
        Contains constraints for a getter method. The name of the corresponding
        property should be given in the "property" option.
      ]]></xsd:documentation>
    </xsd:annotation>
    <xsd:sequence>
      <xsd:element name="constraint" type="constraint" maxOccurs="unbounded" />
    </xsd:sequence>
    <xsd:attribute name="property" type="xsd:string" use="required" />
  </xsd:complexType>

  <xsd:complexType name="constraint" mixed="true">
    <xsd:annotation>
      <xsd:documentation><![CDATA[
        Contains a constraint definition. The name of the constraint should be
        given in the "name" option.

        May contain a single value, multiple "constraint" elements,
        multiple "value" elements or multiple "option" elements.
      ]]></xsd:documentation>
    </xsd:annotation>
    <xsd:choice minOccurs="0">
      <xsd:element name="constraint" type="constraint" minOccurs="1" maxOccurs="unbounded" />
      <xsd:element name="option" type="option" minOccurs="1" maxOccurs="unbounded" />
      <xsd:element name="value" type="value" minOccurs="1" maxOccurs="unbounded" />
    </xsd:choice>
    <xsd:attribute name="name" type="xsd:string" use="required" />
  </xsd:complexType>

  <xsd:complexType name="option" mixed="true">
    <xsd:annotation>
      <xsd:documentation><![CDATA[
        Contains a constraint option definition. The name of the option
        should be given in the "name" option.

        May contain a single value, multiple "value" elements or multiple
        "constraint" elements.
      ]]></xsd:documentation>
    </xsd:annotation>
    <xsd:choice minOccurs="0">
      <xsd:element name="constraint" type="constraint" minOccurs="1" maxOccurs="unbounded" />
      <xsd:element name="value" type="value" minOccurs="1" maxOccurs="unbounded" />
    </xsd:choice>
    <xsd:attribute name="name" type="xsd:string" use="required" />
  </xsd:complexType>

  <xsd:complexType name="value" mixed="true">
    <xsd:annotation>
      <xsd:documentation><![CDATA[
        A value of an element.

        May contain a single value, multiple "value" elements or multiple
        "constraint" elements.
      ]]></xsd:documentation>
    </xsd:annotation>
    <xsd:choice minOccurs="0">
      <xsd:element name="constraint" type="constraint" minOccurs="1" maxOccurs="unbounded" />
      <xsd:element name="value" type="value" minOccurs="1" maxOccurs="unbounded" />
    </xsd:choice>
    <xsd:attribute name="key" type="xsd:string" use="optional" />
  </xsd:complexType>
</xsd:schema>

Solution

  • In the end this turned out to be caused by a bad version of libxml2 on our RHEL5.

    We noticed our service provider had rebooted the system while upgrading packages. The libxml2 package was upgraded to version libxml2-2.6.26-2.1.21.el5_9.2 which has known serious problems validating using XML schemas with certain content in them. The problems cause some XMLs to fail their validation even though they are valid.

    The problem was fixed in build libxml2-2.6.26-2.1.22.el5. After upgrading to this version the forms started working again.