Index: db/models/fields/__init__.py
===================================================================
--- db/models/fields/__init__.py	(revision 7534)
+++ db/models/fields/__init__.py	(working copy)
@@ -1157,6 +1157,11 @@
         self.schema_path = schema_path
         Field.__init__(self, verbose_name, name, **kwargs)
 
+    def formfield(self, **kwargs):
+        defaults = {'form_class': forms.XMLField}
+        defaults.update(kwargs)
+        return super(XMLField, self).formfield(**defaults)
+
     def get_manipulator_field_objs(self):
         return [curry(oldforms.XMLLargeTextField, schema_path=self.schema_path)]
 
Index: newforms/fields.py
===================================================================
--- newforms/fields.py	(revision 7534)
+++ newforms/fields.py	(working copy)
@@ -32,7 +32,7 @@
     'RegexField', 'EmailField', 'FileField', 'ImageField', 'URLField',
     'BooleanField', 'NullBooleanField', 'ChoiceField', 'MultipleChoiceField',
     'ComboField', 'MultiValueField', 'FloatField', 'DecimalField',
-    'SplitDateTimeField', 'IPAddressField', 'FilePathField',
+    'SplitDateTimeField', 'IPAddressField', 'FilePathField', 'XMLField'
 )
 
 # These values, if given to to_python(), will trigger the self.required check.
@@ -782,3 +782,19 @@
 
     def __init__(self, *args, **kwargs):
         super(IPAddressField, self).__init__(ipv4_re, *args, **kwargs)
+
+class XMLField(CharField):
+    """
+    A field that validates XML content against a RelaxNG schema
+    """
+    def __init__(self, schema_path):
+        self.schema_path = schema_path
+
+    def clean(self, value):
+        from django.core.validators import RelaxNGCompact, ValidationError as OldValidationError
+        validator = RelaxNGCompact(self.schema_path)
+        try:
+            validator(value, "") # second arg isn't used but is required
+        except OldValidationError, e:
+            raise ValidationError(e.messages)
+        return value
