diff --git a/gtk/Makefile.am b/gtk/Makefile.am
index 6d5f926452..55758a1144 100644
--- a/gtk/Makefile.am
+++ b/gtk/Makefile.am
@@ -947,6 +947,12 @@ EXTRA_DIST += $(gtk_private_h_sources) $(gtk_extra_sources)
EXTRA_DIST += $(gtk_built_sources)
EXTRA_DIST += $(STOCK_ICONS)
+
+pkgdatadir=$(datadir)/gtk-$(GTK_API_VERSION)
+pkgdata_DATA = gtkbuilder.rng
+
+EXTRA_DIST += gtkbuilder.rnc gtkbuilder.rng
+
DND_CURSORS = \
cursor_dnd_ask.png \
cursor_dnd_copy.png \
diff --git a/gtk/gtkbuilder.c b/gtk/gtkbuilder.c
index f4904fa9b2..1f9d6e4738 100644
--- a/gtk/gtkbuilder.c
+++ b/gtk/gtkbuilder.c
@@ -56,41 +56,18 @@
*
GtkBuilder UI Definitions
*
* GtkBuilder parses textual descriptions of user interfaces which are specified
- * in an XML format which can be roughly described by the DTD below. We refer to
- * these descriptions as GtkBuilder UI definitions or
- * just UI definitions if the context is clear. Do not
+ * in an XML format which can be roughly described by the RELAX NG schema below.
+ * We refer to these descriptions as GtkBuilder UI definitions
+ * or just UI definitions if the context is clear. Do not
* confuse GtkBuilder UI Definitions with
* GtkUIManager UI Definitions, which are more
* limited in scope.
*
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- * ]]>
+ *
+ *
+ * FIXME: MISSING XINCLUDE CONTENT
+ *
+ *
*
* The toplevel element is <interface>. It optionally takes a "domain"
* attribute, which will make the builder look for translated strings using
diff --git a/gtk/gtkbuilder.rnc b/gtk/gtkbuilder.rnc
new file mode 100644
index 0000000000..a2b40320b9
--- /dev/null
+++ b/gtk/gtkbuilder.rnc
@@ -0,0 +1,86 @@
+start = element interface {
+ attribute domain { text } ?,
+ ( requires | object | menu ) *
+}
+
+requires = element requires {
+ attribute lib { text },
+ attribute version { text }
+}
+
+object = element object {
+ attribute id { xsd:ID },
+ attribute class { text },
+ attribute type-func { text } ?,
+ attribute constructor { text } ?,
+ (property | signal | child | ANY) *
+}
+
+property = element property {
+ attribute name { text },
+ attribute translatable { "yes" | "no" } ?,
+ attribute comments { text } ?,
+ attribute context { text } ?,
+ text ?
+}
+
+signal = element signal {
+ attribute name { text },
+ attribute handler { text },
+ attribute after { text } ?,
+ attribute swapped { text } ?,
+ attribute object { text } ?,
+ attribute last_modification_time { text } ?,
+ empty
+}
+
+child = element child {
+ attribute type { text } ?,
+ attribute internal-child { text } ?,
+ (object | ANY)*
+}
+
+menu = element menu {
+ attribute id { xsd:ID },
+ attribute domain { text } ?,
+ (item | submenu | section) *
+}
+
+item = element item {
+ attribute id { xsd:ID } ?,
+ (attribute_ | link) *
+}
+
+attribute_ = element attribute {
+ attribute name { text },
+ attribute type { text } ?,
+ attribute translatable { "yes" | "no" } ?,
+ attribute context { text } ?,
+ attribute comments { text } ?,
+ text ?
+}
+
+link = element link {
+ attribute id { xsd:ID } ?,
+ attribute name { text },
+ item *
+}
+
+submenu = element submenu {
+ attribute id { xsd:ID } ?,
+ (attribute_ | item | submenu | section) *
+}
+
+section = element section {
+ attribute id { xsd:ID } ?,
+ (attribute_ | item | submenu | section) *
+}
+
+ANY = element * - (interface | requires | object | property | signal | child | menu | item | attribute | link | submenu | section) {
+ attribute * { text } *,
+ (ALL * & text ?)
+}
+ALL = element * {
+ attribute * { text } *,
+ (ALL * & text ?)
+}
diff --git a/gtk/gtkbuilder.rng b/gtk/gtkbuilder.rng
new file mode 100644
index 0000000000..e36d05194a
--- /dev/null
+++ b/gtk/gtkbuilder.rng
@@ -0,0 +1,305 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ yes
+ no
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ yes
+ no
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ interface
+ requires
+ object
+ property
+ signal
+ child
+ menu
+ item
+ attribute
+ link
+ submenu
+ section
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+