]> git.saurik.com Git - wxWidgets.git/commitdiff
Add RELAX NG schema for XRC files.
authorVáclav Slavík <vslavik@fastmail.fm>
Thu, 3 Oct 2013 11:08:57 +0000 (11:08 +0000)
committerVáclav Slavík <vslavik@fastmail.fm>
Thu, 3 Oct 2013 11:08:57 +0000 (11:08 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@74927 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

docs/doxygen/overviews/xrc_format.h
misc/schema/xrc_schema.rnc [new file with mode: 0644]
misc/schema/xrc_schema_builtin_only.rnc [new file with mode: 0644]

index f54d08a215a2830750229406c83b357c8648ad7a..408caa67873dd22080b6d59a526bd9df2caf6ded 100644 (file)
@@ -22,6 +22,9 @@
 This document describes the format of XRC resource files, as used by
 wxXmlResource.
 
 This document describes the format of XRC resource files, as used by
 wxXmlResource.
 
+Formal description in the form of a RELAX NG schema is located in the
+@c misc/schema subdirectory of the wxWidgets sources.
+
 XRC file is a XML file with all of its elements in the
 @c http://www.wxwidgets.org/wxxrc namespace. For backward compatibility,
 @c http://www.wxwindows.org/wxxrc namespace is accepted as well (and treated
 XRC file is a XML file with all of its elements in the
 @c http://www.wxwidgets.org/wxxrc namespace. For backward compatibility,
 @c http://www.wxwindows.org/wxxrc namespace is accepted as well (and treated
diff --git a/misc/schema/xrc_schema.rnc b/misc/schema/xrc_schema.rnc
new file mode 100644 (file)
index 0000000..c25c799
--- /dev/null
@@ -0,0 +1,1587 @@
+#
+# RELAX NG schema for XRC files.
+#
+# See http://docs.wxwidgets.org/trunk/overview_xrcformat.html for freeform
+# description of the format.
+#
+#
+#  Extending the grammar
+# -----------------------
+#
+# The grammar defined below validates all builtin <object> classes. Because the
+# XRC format is extensible, it allows any content in <object> nodes that have
+# non-builtin class.
+#
+# This can be customized by overriding the 'customClasses' rule in the grammar
+# when including it from another custom grammar file.
+#
+# For example, if you wish to validate that only wx's builtin classes are used,
+# you can disallow any custom <object>s (see xrc_schema_builtin_only.rnc):
+#
+#     include "xrc_schema.rnc" {
+#         customClasses = notAllowed
+#     }
+#
+# You can also add validation for custom classes:
+#
+#     include "xrc_schema.rnc" {
+#         customClasses = myExtensionClasses
+#     }
+#
+#     myExtensionClasses = (MyFoo | MyBar | ...)
+#     MyFoo =
+#         element object {
+#             attribute class { "MyFoo" },
+#             stdObjectNodeAttributes,
+#             ...
+#         }
+#     ...
+#
+
+default namespace = "http://www.wxwidgets.org/wxxrc"
+namespace xrc = "http://www.wxwidgets.org/wxxrc"
+
+start =
+    element resource {
+        # Versions 2.3.0.1 and 2.5.3.0 differ only in how is '\\' interpreted
+        # in textual content. That's not even validated here, so we accept
+        # both.  Additionally, even though the attribute is optional in the
+        # spec, we require it here; in other words, the schema cannot be used
+        # to validate XRC files from previous millennium.
+        attribute version { "2.3.0.1" | "2.5.3.0" },
+
+        toplevelObjectNode*
+    }
+
+
+# IMPLEMENTATION NOTES:
+#
+# The guiding principle for writing this schema is to validate as much as we
+# possible can, but without introducing false negatives; it is not acceptable
+# to fail validation of a valid (per the human-readable XRC spec) XRC file.
+#
+# Unfortunately, there are some noteworthy complications when describing the
+# XRC format with a formal schema. Working around them results in uglier and
+# overly permissive schema:
+#
+#
+# (1) The biggest issue is with the 'platform' attribute, which may be used on
+# _any_ node in an XRC document. There's no way to specify "universal"
+# attributes that can be placed anywhere in RELAX NG, so we must add the
+# attribute everywhere. The 'platform' grammar rule is used for this and it has
+# an alias, '_', for reduced verbosity. Typical use:
+#
+#       element size   {_, t_size }? &
+#
+#
+# (2) The other 'platform'-related issue is that it messes up cardinality of
+# properties elements. Properties can only be specified once, so the two forms
+# for describing properties are
+#
+#       1. element size {_, t_size }?   # optional property
+#       2. element size {_, t_size }    # required property
+#
+# But this is problematic with 'platform', because it's reasonable (and,
+# indeed, done in the wild) to set properties differently for different
+# platforms:
+#
+#       <object class="wxMenuItem" name="menu_new_from_pot">
+#           <label platform="win">New catalog from POT file...</label>
+#           <label platform="unix|mac">New Catalog from POT File...</label>
+#       </object>
+#
+# But we now have the 'label' property _twice_ and validation fails. The
+# simplest fix is to change the cardinality of properties to allow this [A]:
+#
+#       1. element size {_, t_size }*    # optional property (0 or more times)
+#       2. element size {_, t_size }+    # required property (at least once)
+#
+# Of course, this is too lax and allows invalid (but gracefully handled by
+# wxXmlResource) markup like this:
+#
+#       <object class="wxMenuItem" name="menu_new_from_pot">
+#           <label>Something</label>
+#           <label>Else</label>
+#       </object>
+#
+# We could make this better by splitting the property declaration into two, one
+# for the case with 'platform' and one for without [B]:
+#
+#       (element size { t_size } | element size { attribute platform{string}, t_size }+)
+#
+# But this is verbose and unreadable with the amount of properties present in
+# the schema. Instead, we use the more-forbidding version and annotate
+# properties with 'p' annotation (for "property") that has either 'r'
+# (required) or 'o' (optional) value:
+#
+#       [xrc:p="o"] element checked { t_bool }*  # optional
+#       [xrc:p="r"] element label { t_text }+    # required
+#
+# This makes it possible to implement tools that translate this schema into a
+# variant that use [B].
+#
+
+toplevelObjectNode = (objectRef | builtinToplevelClasses | customClasses)
+windowNode =         (objectRef | builtinWindowClasses | customClasses)
+sizerNode  =         (objectRef | builtinSizerClasses | customClasses)
+
+# The following three lists must be updated when a new class is added
+# to this file.
+
+builtinToplevelClasses =
+    ( builtinWindowClasses
+    | idsRange
+    | wxBitmap_or_wxIcon
+    | wxMenuBar
+    | wxMenu
+    )
+
+builtinWindowClasses =
+    ( unknown
+    | wxAnimationCtrl
+    | wxAuiNotebook
+    | wxBannerWindow
+    | wxBitmapButton
+    | wxBitmapComboBox
+    | wxBitmapToggleButton
+    | wxButton
+    | wxCalendarCtrl
+    | wxCheckBox
+    | wxCheckListBox
+    | wxChoice
+    | wxChoicebook
+    | wxCommandLinkButton
+    | wxCollapsiblePane
+    | wxColourPickerCtrl
+    | wxComboBox
+    | wxComboCtrl
+    | wxDatePickerCtrl
+    | wxDialog
+    | wxDirPickerCtrl
+    | wxEditableListBox
+    | wxFileCtrl
+    | wxFilePickerCtrl
+    | wxFontPickerCtrl
+    | wxFrame
+    | wxGauge
+    | wxGenericDirCtrl
+    | wxGrid
+    | wxHtmlWindow
+    | wxHyperlinkCtrl
+    | wxListBox
+    | wxListbook
+    | wxListCtrl
+    | wxMDIParentFrame
+    | wxNotebook
+    | wxOwnerDrawnComboBox
+    | wxPanel
+    | wxPropertySheetDialog
+    | wxRadioButton
+    | wxRadioBox
+    | wxRibbonBar
+    | wxRibbonButtonBar
+    | wxRibbonControl
+    | wxRibbonGallery
+    | wxRibbonPage
+    | wxRibbonPanel
+    | wxRichTextCtrl
+    | wxScrollBar
+    | wxScrolledWindow
+    | wxSimpleHtmlListBox
+    | wxSlider
+    | wxSpinButton
+    | wxSpinCtrl
+    | wxSplitterWindow
+    | wxSearchCtrl
+    | wxStatusBar
+    | wxStaticBitmap
+    | wxStaticBox
+    | wxStaticLine
+    | wxStaticText
+    | wxTextCtrl
+    | wxTimePickerCtrl
+    | wxToggleButton
+    | wxToolBar
+    | wxToolbook
+    | wxTreeCtrl
+    | wxTreebook
+    | wxWizard
+    )
+
+builtinSizerClasses =
+    ( wxBoxSizer
+    | wxStaticBoxSizer
+    | wxGridSizer
+    | wxFlexGridSizer
+    | wxGridBagSizer
+    | wxWrapSizer
+    | wxStdDialogButtonSizer
+    )
+
+builtinClassesNames =
+    ( "wxBitmap"
+    | "wxIcon"
+    | "wxMenuBar"
+    | "wxMenu"
+
+    | "unknown"
+
+    | "wxAnimationCtrl"
+    | "wxAuiNotebook"
+    | "wxBannerWindow"
+    | "wxBitmapButton"
+    | "wxBitmapComboBox"
+    | "wxBitmapToggleButton"
+    | "wxButton"
+    | "wxCalendarCtrl"
+    | "wxCheckBox"
+    | "wxCheckListBox"
+    | "wxChoice"
+    | "wxChoicebook"
+    | "wxCommandLinkButton"
+    | "wxCollapsiblePane"
+    | "wxColourPickerCtrl"
+    | "wxComboBox"
+    | "wxComboCtrl"
+    | "wxDatePickerCtrl"
+    | "wxDialog"
+    | "wxDirPickerCtrl"
+    | "wxEditableListBox"
+    | "wxFileCtrl"
+    | "wxFilePickerCtrl"
+    | "wxFontPickerCtrl"
+    | "wxFrame"
+    | "wxGauge"
+    | "wxGenericDirCtrl"
+    | "wxGrid"
+    | "wxHtmlWindow"
+    | "wxHyperlinkCtrl"
+    | "wxListBox"
+    | "wxListbook"
+    | "wxListCtrl"
+    | "wxMDIParentFrame"
+    | "wxNotebook"
+    | "wxOwnerDrawnComboBox"
+    | "wxPanel"
+    | "wxPropertySheetDialog"
+    | "wxRadioButton"
+    | "wxRadioBox"
+    | "wxRibbonBar"
+    | "wxRibbonButtonBar"
+    | "wxRibbonControl"
+    | "wxRibbonGallery"
+    | "wxRibbonPage"
+    | "wxRibbonPanel"
+    | "wxRichTextCtrl"
+    | "wxScrollBar"
+    | "wxScrolledWindow"
+    | "wxSimpleHtmlListBox"
+    | "wxSlider"
+    | "wxSpinButton"
+    | "wxSpinCtrl"
+    | "wxSplitterWindow"
+    | "wxSearchCtrl"
+    | "wxStatusBar"
+    | "wxStaticBitmap"
+    | "wxStaticBox"
+    | "wxStaticLine"
+    | "wxStaticText"
+    | "wxTextCtrl"
+    | "wxTimePickerCtrl"
+    | "wxToggleButton"
+    | "wxToolBar"
+    | "wxToolbook"
+    | "wxTreeCtrl"
+    | "wxTreebook"
+    | "wxWizard"
+
+    | "wxBoxSizer"
+    | "wxStaticBoxSizer"
+    | "wxGridSizer"
+    | "wxFlexGridSizer"
+    | "wxGridBagSizer"
+    | "wxWrapSizer"
+    | "wxStdDialogButtonSizer"
+    )
+
+# class names not used at toplevel, only within something else
+builtinNestedClassesNames =
+    ( "wxMenuItem"
+    | "separator"
+    | "break"
+    | "space"
+    | "tool"
+    | "panewindow"
+    | "notebookpage"
+    | "choicebookpage"
+    | "listbookpage"
+    | "treebookpage"
+    | "propertysheetpage"
+    | "ownerdrawnitem"
+    | "listcol"
+    | "listitem"
+    | "wxMDIChildFrame"
+    | "page" | "panel" | "button" | "item"  # wxRibbon classes
+    | "wxWizardPage"
+    | "wxWizardPageSimple"
+    )
+
+allPossibleBuiltinClassNames = (builtinClassesNames | builtinNestedClassesNames)
+
+
+# This grammar rule can be used to plug in any extensions used in an
+# application. By default, it allows any content under custom <object>
+# nodes.
+customClasses =
+    element object {
+        attribute class { string - allPossibleBuiltinClassNames } &
+        stdObjectNodeAttributes &
+        anyXMLContent*
+    }
+
+# Helper for specifying arbitrary content.
+anyXMLContent =
+  element * {
+    (attribute * { text }
+     | text
+     | anyXMLContent)*
+  }
+
+
+# Annotations used to mark special kinds of content:
+#
+# [xrc:p] marks properties, with two possible values:
+#
+#       [xrc:p="r"]     for required properties
+#       [xrc:p="o"]     for optional properties
+#
+
+
+# All <object> nodes (except the pseudo-classes) have these attributes.
+stdObjectNodeAttributes =
+        attribute subclass { t_identifier }? &
+        attribute name     { t_identifier }? &
+        platform
+
+# All (almost) wxWindow-derived objects have these properties.
+stdWindowProperties =
+        [xrc:p="o"] element pos     {_, t_position }* &
+        [xrc:p="o"] element size    {_, t_size }* &
+        [xrc:p="o"] element style   {_, t_style }* &
+        [xrc:p="o"] element exstyle {_, t_style }* &
+        [xrc:p="o"] element fg      {_, t_colour }* &
+        [xrc:p="o"] element ownfg   {_, t_colour }* &
+        [xrc:p="o"] element bg      {_, t_colour }* &
+        [xrc:p="o"] element ownbg   {_, t_colour }* &
+        [xrc:p="o"] element enabled {_, t_bool }* &
+        [xrc:p="o"] element focused {_, t_bool }* &
+        [xrc:p="o"] element hidden  {_, t_bool }* &
+        [xrc:p="o"] element tooltip {_, t_text }* &
+        [xrc:p="o"] element font    {_, t_font }* &
+        [xrc:p="o"] element ownfont {_, t_font }* &
+        [xrc:p="o"] element help    {_, t_text }*
+
+platform =
+        attribute platform {
+            xsd:string { pattern = "(win|mac|unix|os2)( *\| *(win|mac|unix|os2))*" }
+        }?
+# shorthand alias for 'platform' for use in properties definitions and
+# elsewhere where 'platform' would be too verbose
+_ = platform
+
+
+# Basic data types.
+
+t_identifier = string
+t_text       = string
+t_string     = string
+t_bool       = "1" | "0"
+t_integer    = xsd:integer
+t_float      = xsd:float
+t_direction  = "wxLEFT" | "wxRIGHT" | "wxTOP" | "wxBOTTOM"
+t_style      = xsd:string { pattern = "(wx[A-Z_]+)( *\| *(wx[A-Z_]+))*" }
+
+t_url        = string
+t_colour     = xsd:string { pattern = "#[0-9a-zA-Z][0-9a-zA-Z][0-9a-zA-Z][0-9a-zA-Z][0-9a-zA-Z][0-9a-zA-Z]" } |
+               xsd:string { pattern = "[^#].*" }
+t_position   = t_size
+t_size       = xsd:string { pattern = "(-?\d+),(-?\d+)d?" }
+t_dimension  = xsd:string { pattern = "(-?\d+)d?" }
+
+t_bitmap     = t_url?,
+               (
+                   attribute stock_id { t_identifier},
+                   attribute stock_client { t_identifier}?
+               )?
+
+t_font       = (
+                   [xrc:p="o"] element size         {_, t_integer }* &
+                   [xrc:p="o"] element style        {_, ("normal" | "italic" | "slant") }* &
+                   [xrc:p="o"] element weight       {_, ("normal" | "bold" | "light") }* &
+                   [xrc:p="o"] element family       {_, ("roman" | "script" | "decorative" | "swiss" |
+                                                         "modern" | "teletype") }* &
+                   [xrc:p="o"] element underlined   {_, t_bool }* &
+                   [xrc:p="o"] element face         {_, t_text }* &
+                   [xrc:p="o"] element encoding     {_, t_text }* &
+                   [xrc:p="o"] element sysfont      {_, ("wxSYS_OEM_FIXED_FONT" | "wxSYS_ANSI_FIXED_FONT" |
+                                                         "wxSYS_ANSI_VAR_FONT" | "wxSYS_SYSTEM_FONT" |
+                                                         "wxSYS_DEVICE_DEFAULT_FONT" | "wxSYS_SYSTEM_FIXED_FONT" |
+                                                         "wxSYS_DEFAULT_GUI_FONT") }* &
+                   [xrc:p="o"] element inherit      {_, t_bool }* &
+                   [xrc:p="o"] element relativesize {_, t_float }*
+               )
+
+t_imagelist  = (
+                   [xrc:p="o"] element mask {_, t_bool }* &
+                   [xrc:p="o"] element size {_, t_size }* &
+                   element bitmap {_, t_bitmap }+
+               )
+
+t_list_of_numbers = xsd:string { pattern = "\d+(,\d+)*" }
+
+
+#
+# Handlers for non-<object> content:
+#
+
+idsRange =
+    element ids-range {
+        attribute name  { t_identifier },
+        attribute size  { t_integer }?,
+        attribute start { t_integer }?
+    }
+
+
+objectRef =
+    element object_ref {
+        stdObjectNodeAttributes &
+        attribute ref { t_identifier } &
+        anyXMLContent*
+    }
+
+
+#
+# Handlers for specific <object> classes follow:
+#
+
+unknown =
+    element object {
+        attribute class { "unknown" } &
+        attribute name  { t_identifier } &
+        platform &
+        stdWindowProperties
+    }
+
+
+wxBitmap_or_wxIcon =
+    element object {
+        attribute class { "wxBitmap" | "wxIcon" } &
+        stdObjectNodeAttributes &
+        t_bitmap
+    }
+
+
+wxAnimationCtrl =
+    element object {
+        attribute class { "wxAnimationCtrl" } &
+        stdObjectNodeAttributes &
+        stdWindowProperties &
+        [xrc:p="o"] element animation       {_, t_url }* &
+        [xrc:p="o"] element inactive-bitmap {_, t_bitmap }*
+    }
+
+
+wxAuiNotebook =
+    element object {
+        attribute class { "wxAuiNotebook" } &
+        stdObjectNodeAttributes &
+        stdWindowProperties &
+        (wxAuiNotebook_notebookpage | objectRef)*
+    }
+
+wxAuiNotebook_notebookpage =
+    element object {
+        attribute class  { "notebookpage" } &
+        [xrc:p="r"] element label    {_, t_text }+ &
+        [xrc:p="o"] element bitmap   {_, t_bitmap }* &
+        [xrc:p="o"] element selected {_, t_bool }* &
+        windowNode
+    }
+
+
+wxBannerWindow =
+    element object {
+        attribute class { "wxBannerWindow" } &
+        stdObjectNodeAttributes &
+        stdWindowProperties &
+        [xrc:p="o"] element direction {_, t_direction }* &
+        [xrc:p="o"](
+           element bitmap {_, t_bitmap } |
+           (
+               element gradient-start {_, t_colour} &
+               element gradient-end {_, t_colour }
+           )
+        )* &
+        [xrc:p="o"] element title     {_, t_text }* &
+        [xrc:p="o"] element message   {_, t_text }*
+    }
+
+
+wxBitmapButton =
+    element object {
+        attribute class { "wxBitmapButton" } &
+        stdObjectNodeAttributes &
+        stdWindowProperties &
+        [xrc:p="o"] element default  {_, t_bool }* &
+        [xrc:p="r"] element bitmap   {_, t_bitmap }+ &
+        [xrc:p="o"] element selected {_, t_bitmap }* &
+        [xrc:p="o"] element focus    {_, t_bitmap }* &
+        [xrc:p="o"] element disabled {_, t_bitmap }* &
+        [xrc:p="o"] element hover    {_, t_bitmap }*
+    }
+
+
+wxBitmapComboBox =
+    element object {
+        attribute class { "wxBitmapComboBox" } &
+        stdObjectNodeAttributes &
+        stdWindowProperties &
+        [xrc:p="o"] element selection {_, t_integer }* &
+        [xrc:p="o"] element value     {_, t_text }* &
+        (wxBitmapComboBox_ownerdrawnitem | objectRef)*
+    }
+
+wxBitmapComboBox_ownerdrawnitem =
+    element object {
+        attribute class  { "ownerdrawnitem" } &
+        platform &
+        [xrc:p="r"] element text     {_, t_text }+ &
+        [xrc:p="o"] element bitmap   {_, t_bitmap }*
+    }
+
+
+wxBitmapToggleButton =
+    element object {
+        attribute class { "wxBitmapToggleButton" } &
+        stdObjectNodeAttributes &
+        stdWindowProperties &
+        [xrc:p="r"] element bitmap  {_, t_bitmap }+ &
+        [xrc:p="o"] element checked {_, t_bool }*
+    }
+
+
+wxButton =
+    element object {
+        attribute class { "wxButton" } &
+        stdObjectNodeAttributes &
+        stdWindowProperties &
+        [xrc:p="o"] element label          {_, t_text }* &
+        [xrc:p="o"] element bitmap         {_, t_bitmap }* &
+        [xrc:p="o"] element bitmapposition {_, t_direction }* &
+        [xrc:p="o"] element default        {_, t_bool }*
+    }
+
+
+wxCalendarCtrl =
+    element object {
+        attribute class { "wxCalendarCtrl" } &
+        stdObjectNodeAttributes &
+        stdWindowProperties
+    }
+
+
+wxCheckBox =
+    element object {
+        attribute class { "wxCheckBox" } &
+        stdObjectNodeAttributes &
+        stdWindowProperties &
+        [xrc:p="o"] element label   {_, t_text }* &
+        [xrc:p="o"] element checked {_, t_bool }*
+    }
+
+
+wxCheckListBox =
+    element object {
+        attribute class { "wxCheckListBox" } &
+        stdObjectNodeAttributes &
+        stdWindowProperties &
+        element content {
+            platform,
+            element item {
+                attribute checked { t_bool }?,
+                t_text
+            }*
+        }?
+    }
+
+
+wxChoice =
+    element object {
+        attribute class { "wxChoice" } &
+        stdObjectNodeAttributes &
+        stdWindowProperties &
+        [xrc:p="o"] element selection {_, t_integer }* &
+        element content {
+            platform,
+            element item {_, t_text }*
+        }?
+    }
+
+
+wxChoicebook =
+    element object {
+        attribute class { "wxChoicebook" } &
+        stdObjectNodeAttributes &
+        stdWindowProperties &
+        [xrc:p="o"] element imagelist {_, t_imagelist }* &
+        (wxChoicebook_choicebookpage | objectRef)*
+    }
+
+wxChoicebook_choicebookpage =
+    element object {
+        attribute class { "choicebookpage" } &
+        platform &
+        [xrc:p="r"] element label    {_, t_text }+ &
+        [xrc:p="o"](
+            element bitmap {_, t_bitmap } |
+            element image  {_, t_integer }
+        )* &
+        [xrc:p="o"] element selected {_, t_bool }* &
+        windowNode
+    }
+
+
+wxCommandLinkButton =
+    element object {
+        attribute class { "wxCommandLinkButton" } &
+        stdObjectNodeAttributes &
+        stdWindowProperties &
+        [xrc:p="r"] element label {_, t_text }+ &
+        [xrc:p="o"] element note  {_, t_text }*
+    }
+
+
+wxCollapsiblePane =
+    element object {
+        attribute class { "wxCollapsiblePane" } &
+        stdObjectNodeAttributes &
+        stdWindowProperties &
+        [xrc:p="r"] element label     {_, t_text }+ &
+        [xrc:p="o"] element collapsed {_, t_bool }* &
+        (wxCollapsiblePane_panewindow | objectRef)?
+    }
+
+wxCollapsiblePane_panewindow =
+    element object {
+        attribute class { "panewindow" } &
+        platform &
+        (sizerNode | windowNode)
+    }
+
+
+wxColourPickerCtrl =
+    element object {
+        attribute class { "wxColourPickerCtrl" } &
+        stdObjectNodeAttributes &
+        stdWindowProperties &
+        [xrc:p="o"] element value {_, t_colour }*
+    }
+
+
+wxComboBox =
+    element object {
+        attribute class { "wxComboBox" } &
+        stdObjectNodeAttributes &
+        stdWindowProperties &
+        [xrc:p="o"] element selection {_, t_integer }* &
+        [xrc:p="o"] element value     {_, t_string }* &
+        element content {
+            platform,
+            element item {_, t_text }*
+        }?
+    }
+
+
+wxComboCtrl =
+    element object {
+        attribute class { "wxComboCtrl" } &
+        stdObjectNodeAttributes &
+        stdWindowProperties &
+        [xrc:p="o"] element value {_, t_string }*
+    }
+
+
+wxDatePickerCtrl =
+    element object {
+        attribute class { "wxDatePickerCtrl" } &
+        stdObjectNodeAttributes &
+        stdWindowProperties
+    }
+
+
+wxDialog =
+    element object {
+        attribute class { "wxDialog" } &
+        stdObjectNodeAttributes &
+        stdWindowProperties &
+        [xrc:p="o"] element title    {_, t_text }* &
+        [xrc:p="o"] element icon     {_, t_bitmap }* &
+        [xrc:p="o"] element centered {_, t_bool }* &
+        (sizerNode | windowNode* )?
+    }
+
+
+wxDirPickerCtrl =
+    element object {
+        attribute class { "wxDirPickerCtrl" } &
+        stdObjectNodeAttributes &
+        stdWindowProperties &
+        [xrc:p="o"] element value   {_, t_string }* &
+        [xrc:p="r"] element message {_, t_text}+
+    }
+
+
+wxEditableListBox =
+    element object {
+        attribute class { "wxEditableListBox" } &
+        stdObjectNodeAttributes &
+        stdWindowProperties &
+        [xrc:p="o"] element label {_, t_text}* &
+        element content {
+            platform,
+            element item {_, t_text }*
+        }?
+    }
+
+
+wxFileCtrl =
+    element object {
+        attribute class { "wxFileCtrl" } &
+        stdObjectNodeAttributes &
+        stdWindowProperties &
+        [xrc:p="o"] element value    {_, t_string }* &
+        [xrc:p="r"] element message  {_, t_text }+ &
+        [xrc:p="o"] element wildcard {_, t_string }*
+    }
+
+
+wxFilePickerCtrl =
+    element object {
+        attribute class { "wxFilePickerCtrl" } &
+        stdObjectNodeAttributes &
+        stdWindowProperties &
+        [xrc:p="o"] element value    {_, t_string }* &
+        [xrc:p="r"] element message  {_, t_text }+ &
+        [xrc:p="o"] element wildcard {_, t_string }*
+    }
+
+
+wxFontPickerCtrl =
+    element object {
+        attribute class { "wxFontPickerCtrl" } &
+        stdObjectNodeAttributes &
+        stdWindowProperties &
+        [xrc:p="o"] element value {_, t_font }*
+    }
+
+
+wxFrame =
+    element object {
+        attribute class { "wxFrame" } &
+        stdObjectNodeAttributes &
+        stdWindowProperties &
+        [xrc:p="o"] element title    {_, t_text }* &
+        [xrc:p="o"] element icon     {_, t_bitmap }* &
+        [xrc:p="o"] element centered {_, t_bool }* &
+        (sizerNode | windowNode* )?
+    }
+
+
+wxGauge =
+    element object {
+        attribute class { "wxGauge" } &
+        stdObjectNodeAttributes &
+        stdWindowProperties &
+        [xrc:p="o"] element range  {_, t_integer }* &
+        [xrc:p="o"] element value  {_, t_integer }* &
+        [xrc:p="o"] element shadow {_, t_dimension }* &
+        [xrc:p="o"] element bezel  {_, t_dimension }*
+    }
+
+
+wxGenericDirCtrl =
+    element object {
+        attribute class { "wxGenericDirCtrl" } &
+        stdObjectNodeAttributes &
+        stdWindowProperties &
+        [xrc:p="o"] element defaultfolder {_, t_string }* &
+        [xrc:p="o"] element filter        {_, t_text }* &
+        [xrc:p="o"] element defaultfilter {_, t_integer }*
+    }
+
+
+wxGrid =
+    element object {
+        attribute class { "wxGrid" } &
+        stdObjectNodeAttributes &
+        stdWindowProperties
+    }
+
+
+wxHtmlWindow =
+    element object {
+        attribute class { "wxHtmlWindow" } &
+        stdObjectNodeAttributes &
+        stdWindowProperties &
+        [xrc:p="o"](
+            element url       {_, t_url } |
+            element htmlcode  {_, t_text }
+        )* &
+        [xrc:p="o"] element borders {_, t_dimension }*
+    }
+
+
+wxHyperlinkCtrl =
+    element object {
+        attribute class { "wxHyperlinkCtrl" } &
+        stdObjectNodeAttributes &
+        stdWindowProperties &
+        [xrc:p="r"] element label {_, t_text }+ &
+        [xrc:p="r"] element url   {_, t_url }+
+    }
+
+
+wxListBox =
+    element object {
+        attribute class { "wxListBox" } &
+        stdObjectNodeAttributes &
+        stdWindowProperties &
+        [xrc:p="o"] element selection {_, t_integer }* &
+        element content {
+            platform,
+            element item {_, t_text }*
+        }?
+    }
+
+
+wxListbook =
+    element object {
+        attribute class { "wxListbook" } &
+        stdObjectNodeAttributes &
+        stdWindowProperties &
+        [xrc:p="o"] element imagelist {_, t_imagelist }* &
+        (wxListbook_listbookpage | objectRef)*
+    }
+
+wxListbook_listbookpage =
+    element object {
+        attribute class { "listbookpage" } &
+        [xrc:p="r"] element label    {_, t_text }+ &
+        [xrc:p="o"](
+            element bitmap {_, t_bitmap } |
+            element image  {_, t_integer }
+        )* &
+        [xrc:p="o"] element selected {_, t_bool }* &
+        windowNode
+    }
+
+
+wxListCtrl =
+    element object {
+        attribute class { "wxListCtrl" } &
+        stdObjectNodeAttributes &
+        stdWindowProperties &
+        [xrc:p="o"] element imagelist {_, t_imagelist }* &
+        [xrc:p="o"] element imagelist-small {_, t_imagelist }* &
+        (wxListCtrl_listcol | wxListCtrl_listitem | objectRef)*
+    }
+
+wxListCtrl_listcol =
+    element object {
+        attribute class { "listcol" } &
+        platform &
+        [xrc:p="o"] element align   {_, ("wxLIST_FORMAT_LEFT" | "wxLIST_FORMAT_RIGHT" |
+                                         "wxLIST_FORMAT_CENTRE") }* &
+        [xrc:p="o"] element text    {_, t_text }* &
+        [xrc:p="o"] element width   {_, t_integer }* &
+        [xrc:p="o"] element image   {_, t_integer }*
+    }
+
+wxListCtrl_listitem =
+    element object {
+        attribute class { "listitem" } &
+        platform &
+        [xrc:p="o"] element align        {_, ("wxLIST_FORMAT_LEFT" | "wxLIST_FORMAT_RIGHT" |
+                                              "wxLIST_FORMAT_CENTRE") }* &
+        [xrc:p="o"] element bg           {_, t_colour }* &
+        [xrc:p="o"] element col          {_, t_integer }* &
+        [xrc:p="o"] element data         {_, t_integer }* &
+        [xrc:p="o"] element font         {_, t_font }* &
+        [xrc:p="o"] element state        {_, ("wxLIST_STATE_FOCUSED" | "wxLIST_STATE_SELECTED") }* &
+        [xrc:p="o"] element text         {_, t_text }* &
+        [xrc:p="o"] element textcolour   {_, t_colour }* &
+        [xrc:p="o"](
+            element bitmap   {_, t_bitmap } |
+            element image    {_, t_integer }
+        )* &
+        [xrc:p="o"](
+            element bitmap-small {_, t_bitmap } |
+            element image-small  {_, t_integer }
+        )*
+    }
+
+
+wxMDIParentFrame =
+    element object {
+        attribute class { "wxMDIParentFrame" } &
+        stdObjectNodeAttributes &
+        stdWindowProperties &
+        [xrc:p="o"] element title    {_, t_text }* &
+        [xrc:p="o"] element icon     {_, t_bitmap }* &
+        [xrc:p="o"] element centered {_, t_bool }* &
+        (wxMDIChildFrame | objectRef)*
+    }
+
+wxMDIChildFrame =
+    element object {
+        attribute class { "wxMDIChildFrame" } &
+        stdObjectNodeAttributes &
+        stdWindowProperties &
+        [xrc:p="o"] element title    {_, t_text }* &
+        [xrc:p="o"] element icon     {_, t_bitmap }* &
+        [xrc:p="o"] element centered {_, t_bool }* &
+        (sizerNode | windowNode* )?
+    }
+
+
+wxMenuBar =
+    element object {
+        attribute class { "wxMenuBar" } &
+        stdObjectNodeAttributes &
+        [xrc:p="o"] element style {_, t_style }* &
+        (wxMenu | objectRef)*
+    }
+
+wxMenu =
+    element object {
+        attribute class { "wxMenu" } &
+        stdObjectNodeAttributes &
+        [xrc:p="o"] element label   {_, t_text }* &
+        [xrc:p="o"] element style   {_, t_style }* &
+        [xrc:p="o"] element help    {_, t_text }* &
+        [xrc:p="o"] element enabled {_, t_bool }* &
+        (
+            wxMenuItem |
+            wxMenu |
+            objectRef |
+            element object { attribute class { "separator" }, platform } |
+            element object { attribute class { "break" },     platform }
+        )*
+    }
+
+wxMenuItem =
+    element object {
+        attribute class { "wxMenuItem" } &
+        stdObjectNodeAttributes &
+        [xrc:p="o"] element label     {_, t_text }* &
+        [xrc:p="o"] element accel     {_, t_text }* &
+        [xrc:p="o"] element radio     {_, t_bool }* &
+        [xrc:p="o"] element checkable {_, t_bool }* &
+        [xrc:p="o"] element bitmap    {_, t_bitmap }* &
+        [xrc:p="o"] element bitmap2   {_, t_bitmap }* &
+        [xrc:p="o"] element help      {_, t_text }* &
+        [xrc:p="o"] element enabled   {_, t_bool }* &
+        [xrc:p="o"] element checked   {_, t_bool }*
+    }
+
+
+wxNotebook =
+    element object {
+        attribute class { "wxNotebook" } &
+        stdObjectNodeAttributes &
+        stdWindowProperties &
+        [xrc:p="o"] element imagelist {_, t_imagelist }* &
+        (wxNotebook_notebookpage | objectRef)*
+    }
+
+wxNotebook_notebookpage =
+    element object {
+        attribute class { "notebookpage" } &
+        platform &
+        [xrc:p="r"] element label    {_, t_text }+ &
+        (
+            element bitmap {_, t_bitmap } |
+            element image  {_, t_integer }
+        )? &
+        [xrc:p="o"] element selected {_, t_bool }* &
+        windowNode
+    }
+
+
+wxOwnerDrawnComboBox =
+    element object {
+        attribute class { "wxOwnerDrawnComboBox" } &
+        stdObjectNodeAttributes &
+        stdWindowProperties &
+        [xrc:p="o"] element selection  {_, t_integer }* &
+        [xrc:p="o"] element value      {_, t_string }* &
+        [xrc:p="o"] element buttonsize {_, t_size }* &
+        element content {
+            platform,
+            element item {_, t_text }*
+        }?
+    }
+
+
+wxPanel =
+    element object {
+        attribute class { "wxPanel" } &
+        stdObjectNodeAttributes &
+        stdWindowProperties &
+        (sizerNode | windowNode* )?
+    }
+
+
+wxPropertySheetDialog =
+    element object {
+        attribute class { "wxPropertySheetDialog" } &
+        stdObjectNodeAttributes &
+        stdWindowProperties &
+        [xrc:p="o"] element title    {_, t_text }* &
+        [xrc:p="o"] element icon     {_, t_bitmap }* &
+        [xrc:p="o"] element centered {_, t_bool }* &
+        [xrc:p="o"] element buttons  {_, t_style }* &
+        (wxNotebook_notebookpage | objectRef)*
+    }
+
+wxPropertySheetDialog_propertysheetpage =
+    element object {
+        attribute class { "propertysheetpage" } &
+        platform &
+        [xrc:p="r"] element label    {_, t_text }+ &
+        [xrc:p="o"] element bitmap {_, t_bitmap }* &
+        [xrc:p="o"] element selected {_, t_bool }* &
+        windowNode
+    }
+
+
+wxRadioButton =
+    element object {
+        attribute class { "wxRadioButton" } &
+        stdObjectNodeAttributes &
+        stdWindowProperties &
+        [xrc:p="r"] element label {_, t_text }+ &
+        [xrc:p="o"] element value {_, t_bool }*
+    }
+
+
+wxRadioBox =
+    element object {
+        attribute class { "wxRadioBox" } &
+        stdObjectNodeAttributes &
+        stdWindowProperties &
+        [xrc:p="o"] element label     {_, t_text }* &
+        [xrc:p="o"] element dimension {_, t_integer }* &
+        [xrc:p="o"] element selection {_, t_integer }* &
+        element content {
+            platform,
+            element item {
+                platform,
+                attribute tooltip  { t_string }?,
+                attribute helptext { t_string }?,
+                attribute enabled  { t_bool }?,
+                attribute hidden   { t_bool }?,
+                t_text
+            }*
+        }?
+    }
+
+
+wxRibbonBar =
+    element object {
+        attribute class { "wxRibbonBar" } &
+        stdObjectNodeAttributes &
+        stdWindowProperties &
+        [xrc:p="o"] element art-provider {_, ("default" | "aui" | "msw") }* &
+        (wxRibbonPage | objectRef)*
+    }
+
+wxRibbonButtonBar =
+    element object {
+        attribute class { "wxRibbonButtonBar" } &
+        stdObjectNodeAttributes &
+        stdWindowProperties &
+        (wxRibbonButtonBar_button | objectRef)*
+    }
+
+wxRibbonButtonBar_button =
+    element object {
+        attribute class { "button" } &
+        stdObjectNodeAttributes &
+        [xrc:p="o"] element hybrid                {_, t_bool }* &
+        [xrc:p="o"] element disabled              {_, t_bool }* &
+        [xrc:p="r"] element label                 {_, t_text }+ &
+        [xrc:p="r"] element bitmap                {_, t_bitmap }+ &
+        [xrc:p="o"] element small-bitmap          {_, t_bitmap }* &
+        [xrc:p="o"] element disabled-bitmap       {_, t_bitmap }* &
+        [xrc:p="o"] element small-disabled-bitmap {_, t_bitmap }* &
+        [xrc:p="o"] element help                  {_, t_text }*
+    }
+
+wxRibbonControl =
+    element object {
+        attribute class { "wxRibbonControl" } &
+        attribute subclass { t_identifier } & # must be subclassed
+        attribute name     { t_identifier }? &
+        platform
+    }
+
+wxRibbonGallery =
+    element object {
+        attribute class { "wxRibbonGallery" } &
+        stdObjectNodeAttributes &
+        stdWindowProperties &
+        (wxRibbonGallery_item | objectRef)*
+    }
+
+wxRibbonGallery_item =
+    element object {
+        attribute class { "item" } &
+        stdObjectNodeAttributes &
+        [xrc:p="o"] element bitmap {_, t_bitmap }*
+    }
+
+wxRibbonPage =
+    element object {
+        # unfortunately, wxRibbonXmlHandler supports "page" alias
+        attribute class { "wxRibbonPage" | "page" } &
+        stdObjectNodeAttributes &
+        stdWindowProperties &
+        [xrc:p="o"] element label {_, t_text }* &
+        [xrc:p="o"] element icon  {_, t_bitmap }* &
+        (wxRibbon_anyControl | objectRef)*
+    }
+
+wxRibbonPanel =
+    element object {
+        # unfortunately, wxRibbonXmlHandler supports "panel" alias
+        attribute class { "wxRibbonPanel" | "panel" } &
+        stdObjectNodeAttributes &
+        stdWindowProperties &
+        [xrc:p="o"] element label {_, t_text }* &
+        [xrc:p="o"] element icon  {_, t_bitmap }* &
+        (sizerNode | wxRibbon_anyControl | objectRef)*
+    }
+
+wxRibbon_anyControl = wxRibbonBar | wxRibbonButtonBar | wxRibbonControl |
+                      wxRibbonGallery | wxRibbonPanel
+
+
+wxRichTextCtrl =
+    element object {
+        attribute class { "wxRichTextCtrl" } &
+        stdObjectNodeAttributes &
+        stdWindowProperties &
+        [xrc:p="o"] element value     {_, t_text }* &
+        [xrc:p="o"] element maxlength {_, t_integer }*
+    }
+
+
+wxScrollBar =
+    element object {
+        attribute class { "wxScrollBar" } &
+        stdObjectNodeAttributes &
+        stdWindowProperties &
+        [xrc:p="o"] element value     {_, t_integer }* &
+        [xrc:p="o"] element range     {_, t_integer }* &
+        [xrc:p="o"] element thumbsize {_, t_integer }* &
+        [xrc:p="o"] element pagesize  {_, t_integer }*
+    }
+
+
+wxScrolledWindow =
+    element object {
+        attribute class { "wxScrolledWindow" } &
+        stdObjectNodeAttributes &
+        stdWindowProperties &
+        [xrc:p="o"] element scrollrate {_, t_size }* &
+        (sizerNode | windowNode* )?
+    }
+
+
+wxSimpleHtmlListBox =
+    element object {
+        attribute class { "wxSimpleHtmlListBox" } &
+        stdObjectNodeAttributes &
+        stdWindowProperties &
+        [xrc:p="o"] element selection {_, t_integer }* &
+        element content {
+            platform,
+            element item {_, t_text }*
+        }?
+    }
+
+
+wxSlider =
+    element object {
+        attribute class { "wxSlider" } &
+        stdObjectNodeAttributes &
+        stdWindowProperties &
+        [xrc:p="o"] element value    {_, t_integer }* &
+        [xrc:p="o"] element min      {_, t_integer }* &
+        [xrc:p="o"] element max      {_, t_integer }* &
+        [xrc:p="o"] element pagesize {_, t_integer }* &
+        [xrc:p="o"] element linesize {_, t_integer }* &
+        [xrc:p="o"] element tickfreq {_, t_integer }* &
+        [xrc:p="o"] element tick     {_, t_integer }* &
+        [xrc:p="o"] element thumb    {_, t_integer }* &
+        [xrc:p="o"] element selmin   {_, t_integer }* &
+        [xrc:p="o"] element selmax   {_, t_integer }*
+    }
+
+
+wxSpinButton =
+    element object {
+        attribute class { "wxSpinButton" } &
+        stdObjectNodeAttributes &
+        stdWindowProperties &
+        [xrc:p="o"] element value {_, t_integer }* &
+        [xrc:p="o"] element min   {_, t_integer }* &
+        [xrc:p="o"] element max   {_, t_integer }*
+    }
+
+
+wxSpinCtrl =
+    element object {
+        attribute class { "wxSpinCtrl" } &
+        stdObjectNodeAttributes &
+        stdWindowProperties &
+        [xrc:p="o"] element value {_, t_integer }* &
+        [xrc:p="o"] element min   {_, t_integer }* &
+        [xrc:p="o"] element max   {_, t_integer }* &
+        [xrc:p="o"] element base  {_, ("10" | "16") }*
+    }
+
+
+wxSplitterWindow =
+    element object {
+        attribute class { "wxSplitterWindow" } &
+        stdObjectNodeAttributes &
+        stdWindowProperties &
+        [xrc:p="o"] element orientation {_, ("vertical" | "horizontal") }* &
+        [xrc:p="o"] element sashpos     {_, t_dimension }* &
+        [xrc:p="o"] element minsize     {_, t_dimension }* &
+        [xrc:p="o"] element gravity     {_, t_float }* &
+        (windowNode, windowNode?) # 1 or 2 child windows
+    }
+
+
+wxSearchCtrl =
+    element object {
+        attribute class { "wxSearchCtrl" } &
+        stdObjectNodeAttributes &
+        stdWindowProperties &
+        [xrc:p="o"] element value {_, t_text }*
+    }
+
+
+wxStatusBar =
+    element object {
+        attribute class { "wxStatusBar" } &
+        stdObjectNodeAttributes &
+        stdWindowProperties &
+        [xrc:p="o"] element fields {_, t_integer }* &
+        [xrc:p="o"] element widths {_, t_list_of_numbers }* &
+        [xrc:p="o"] element styles {_, xsd:string { pattern = "wxSB_(NORMAL|FLAT|RAISED|SUNKEN)(,wxSB_(NORMAL|FLAT|RAISED|SUNKEN))*" } }*
+    }
+
+
+wxStaticBitmap =
+    element object {
+        attribute class { "wxStaticBitmap" } &
+        stdObjectNodeAttributes &
+        stdWindowProperties &
+        element bitmap {_, t_bitmap }
+    }
+
+
+wxStaticBox =
+    element object {
+        attribute class { "wxStaticBox" } &
+        stdObjectNodeAttributes &
+        stdWindowProperties &
+        [xrc:p="o"] element label {_, t_text }*
+    }
+
+
+wxStaticLine =
+    element object {
+        attribute class { "wxStaticLine" } &
+        stdObjectNodeAttributes &
+        stdWindowProperties
+    }
+
+
+wxStaticText =
+    element object {
+        attribute class { "wxStaticText" } &
+        stdObjectNodeAttributes &
+        stdWindowProperties &
+        [xrc:p="o"] element label {_, t_text }* &
+        [xrc:p="o"] element wrap  {_, t_dimension }*
+    }
+
+
+wxTextCtrl =
+    element object {
+        attribute class { "wxTextCtrl" } &
+        stdObjectNodeAttributes &
+        stdWindowProperties &
+        [xrc:p="o"] element value     {_, t_text }* &
+        [xrc:p="o"] element maxlength {_, t_integer }*
+    }
+
+
+wxTimePickerCtrl =
+    element object {
+        attribute class { "wxTimePickerCtrl" } &
+        stdObjectNodeAttributes &
+        stdWindowProperties
+    }
+
+
+wxToggleButton =
+    element object {
+        attribute class { "wxToggleButton" } &
+        stdObjectNodeAttributes &
+        stdWindowProperties &
+        [xrc:p="r"] element label   {_, t_text }+ &
+        [xrc:p="o"] element checked {_, t_bool }*
+    }
+
+
+wxToolBar =
+    element object {
+        attribute class { "wxToolBar" } &
+        stdObjectNodeAttributes &
+        stdWindowProperties &
+        [xrc:p="o"] element bitmapsize        {_, t_size }* &
+        [xrc:p="o"] element margins           {_, t_size }* &
+        [xrc:p="o"] element packing           {_, t_integer }* &
+        [xrc:p="o"] element separation        {_, t_integer }* &
+        [xrc:p="o"] element dontattachtoframe {_, t_bool }* &
+        (
+            windowNode |
+            wxToolBar_tool |
+            element object { attribute class { "separator" }, platform } |
+            element object { attribute class { "space" },     platform }
+        )*
+    }
+
+wxToolBar_tool =
+    element object {
+        attribute class { "tool" } &
+        stdObjectNodeAttributes &
+        [xrc:p="r"] element bitmap   {_, t_bitmap }+ &
+        [xrc:p="o"] element bitmap2  {_, t_bitmap }* &
+        [xrc:p="o"] element label    {_, t_text }* &
+        [xrc:p="o"] element tooltip  {_, t_text }* &
+        [xrc:p="o"] element longhelp {_, t_text }* &
+        [xrc:p="o"] element disabled {_, t_bool }* &
+        [xrc:p="o"] element checked  {_, t_bool }* &
+        [xrc:p="o"](
+            element radio    {_, t_bool } |
+            element toggle   {_, t_bool } |
+            element dropdown {_, wxMenu? }
+        )*
+    }
+
+
+wxToolbook =
+    element object {
+        attribute class { "wxToolbook" } &
+        stdObjectNodeAttributes &
+        stdWindowProperties &
+        [xrc:p="o"] element imagelist {_, t_imagelist }* &
+        (wxToolbook_toolbookpage | objectRef)*
+    }
+
+wxToolbook_toolbookpage =
+    element object {
+        attribute class { "toolbookpage" } &
+        platform &
+        [xrc:p="r"] element label    {_, t_text }+ &
+        [xrc:p="o"](
+            element bitmap {_, t_bitmap } |
+            element image  {_, t_integer }
+        )* &
+        [xrc:p="o"] element selected {_, t_bool }* &
+        windowNode
+    }
+
+
+wxTreeCtrl =
+    element object {
+        attribute class { "wxTreeCtrl" } &
+        stdObjectNodeAttributes &
+        stdWindowProperties &
+        [xrc:p="o"] element imagelist {_, t_imagelist }*
+    }
+
+
+wxTreebook =
+    element object {
+        attribute class { "wxTreebook" } &
+        stdObjectNodeAttributes &
+        stdWindowProperties &
+        [xrc:p="o"] element imagelist {_, t_imagelist }* &
+        (wxTreebook_treebookpage | objectRef)*
+    }
+
+wxTreebook_treebookpage =
+    element object {
+        attribute class { "treebookpage" } &
+        platform &
+        [xrc:p="r"] element depth    {_, t_integer }+ &
+        [xrc:p="r"] element label    {_, t_text }+ &
+        [xrc:p="o"](
+            element bitmap {_, t_bitmap } |
+            element image  {_, t_integer }
+        )* &
+        [xrc:p="o"] element selected {_, t_bool }* &
+        [xrc:p="o"] element expanded {_, t_bool }* &
+        windowNode
+    }
+
+
+wxWizard =
+    element object {
+        attribute class { "wxWizard" } &
+        stdObjectNodeAttributes &
+        stdWindowProperties &
+        [xrc:p="o"] element title  {_, t_text }* &
+        [xrc:p="o"] element bitmap {_, t_bitmap }* &
+        (wxWizardPage_any | objectRef)*
+    }
+
+wxWizardPage_any =
+    element object {
+        attribute class { "wxWizardPage" | "wxWizardPageSimple" } &
+        stdObjectNodeAttributes &
+        stdWindowProperties &
+        [xrc:p="o"] element bitmap {_, t_bitmap }* &
+        (sizerNode | windowNode* )?
+    }
+
+
+
+
+wxSizer_item =
+    element object {
+        (
+            (
+                attribute class { "spacer" } &
+                [xrc:p="o"] element size {_, t_size }*
+            )
+            |
+            (
+                attribute class { "sizeritem" } &
+                (windowNode | sizerNode)
+            )
+        ) &
+        stdObjectNodeAttributes &
+        [xrc:p="o"] element option   {_, t_integer }* &
+        [xrc:p="o"] element flag     {_, t_style }* &
+        [xrc:p="o"] element border   {_, t_dimension }* &
+        [xrc:p="o"] element minsize  {_, t_size }* &
+        [xrc:p="o"] element ratio    {_, t_size }* &
+        # TODO: cell{pos,span} are wxGridBagSizer-only and required in it, this is too lax
+        [xrc:p="o"] element cellpos  {_, t_position }* &
+        [xrc:p="o"] element cellspan {_, t_size }*
+    }
+
+wxBoxSizer =
+    element object {
+        attribute class { "wxBoxSizer" } &
+        stdObjectNodeAttributes &
+        [xrc:p="o"] element minsize {_, t_size }* &
+        [xrc:p="o"] element orient  {_, ("wxHORIZONTAL" | "wxVERTICAL") }* &
+        (wxSizer_item | objectRef)*
+    }
+
+wxStaticBoxSizer =
+    element object {
+        attribute class { "wxStaticBoxSizer" } &
+        stdObjectNodeAttributes &
+        [xrc:p="o"] element minsize {_, t_size }* &
+        [xrc:p="o"] element label   {_, t_text }* &
+        [xrc:p="o"] element orient  {_, ("wxHORIZONTAL" | "wxVERTICAL") }* &
+        (wxSizer_item | objectRef)*
+    }
+
+wxGridSizer =
+    element object {
+        attribute class { "wxGridSizer" } &
+        stdObjectNodeAttributes &
+        [xrc:p="o"] element minsize {_, t_size }* &
+        [xrc:p="o"] element rows    {_, t_integer }* &
+        [xrc:p="o"] element cols    {_, t_integer }* &
+        [xrc:p="o"] element vgap    {_, t_dimension }* &
+        [xrc:p="o"] element hgap    {_, t_dimension }* &
+        (wxSizer_item | objectRef)*
+    }
+
+wxFlexGridSizer =
+    element object {
+        attribute class { "wxFlexGridSizer" } &
+        stdObjectNodeAttributes &
+        [xrc:p="o"] element minsize             {_, t_size }* &
+        [xrc:p="o"] element rows                {_, t_integer }* &
+        [xrc:p="o"] element cols                {_, t_integer }* &
+        [xrc:p="o"] element vgap                {_, t_dimension }* &
+        [xrc:p="o"] element hgap                {_, t_dimension }* &
+        [xrc:p="o"] element flexibledirection   {_, ("wxVERTICAL" | "wxHORIZONTAL" | "wxBOTH") }* &
+        [xrc:p="o"] element nonflexiblegrowmode {_, ("wxFLEX_GROWMODE_NONE" |
+                                                     "wxFLEX_GROWMODE_SPECIFIED" |
+                                                     "wxFLEX_GROWMODE_ALL") }* &
+        [xrc:p="o"] element growablerows        {_, t_list_of_numbers }* &
+        [xrc:p="o"] element growablecols        {_, t_list_of_numbers }* &
+        (wxSizer_item | objectRef)*
+    }
+
+wxGridBagSizer =
+    element object {
+        attribute class { "wxGridBagSizer" } &
+        stdObjectNodeAttributes &
+        [xrc:p="o"] element minsize             {_, t_size }* &
+        [xrc:p="o"] element vgap                {_, t_dimension }* &
+        [xrc:p="o"] element hgap                {_, t_dimension }* &
+        [xrc:p="o"] element flexibledirection   {_, ("wxVERTICAL" | "wxHORIZONTAL" | "wxBOTH") }* &
+        [xrc:p="o"] element nonflexiblegrowmode {_, ("wxFLEX_GROWMODE_NONE" |
+                                                     "wxFLEX_GROWMODE_SPECIFIED" |
+                                                     "wxFLEX_GROWMODE_ALL") }* &
+        [xrc:p="o"] element growablerows        {_, t_list_of_numbers }* &
+        [xrc:p="o"] element growablecols        {_, t_list_of_numbers }* &
+        (wxSizer_item | objectRef)*
+    }
+
+wxWrapSizer =
+    element object {
+        attribute class { "wxWrapSizer" } &
+        stdObjectNodeAttributes &
+        [xrc:p="o"] element minsize {_, t_size }* &
+        [xrc:p="r"] element orient  {_, ("wxHORIZONTAL" | "wxVERTICAL") }+ &
+        [xrc:p="o"] element flag    {_, t_style }* &
+        (wxSizer_item | objectRef)*
+    }
+
+wxStdDialogButtonSizer =
+    element object {
+        attribute class { "wxStdDialogButtonSizer" } &
+        stdObjectNodeAttributes &
+        element object {
+            attribute class { "button" },
+            platform,
+            (wxButton | customClasses | objectRef)
+        }+
+    }
diff --git a/misc/schema/xrc_schema_builtin_only.rnc b/misc/schema/xrc_schema_builtin_only.rnc
new file mode 100644 (file)
index 0000000..e55a991
--- /dev/null
@@ -0,0 +1,12 @@
+#
+# RELAX NG schema for XRC files.
+#
+# Super-strict variant that only accepts wx's builtin classes.
+#
+# See http://docs.wxwidgets.org/trunk/overview_xrcformat.html for freeform
+# description of the format.
+#
+
+include "xrc_schema.rnc" {
+  customClasses = notAllowed
+}