Support for custom tags

Apr 8, 2009 at 12:07 PM
Of course it would be perfect, if custom tags could be supported (for xbl widgets for example).
but i guess that is pretty impossible using xml schemas.

anyway, maybe you know a way. :)

good luck!
Apr 8, 2009 at 2:01 PM
Edited Apr 8, 2009 at 2:10 PM
Okay, I think I found a solution.

First of all: I don't have any knowledge of XML schemas - just digged into it some minutes ago and tried something.

For adding custom elements we could create a new schema "xul_custom_elements.xsd". This one will include "xul.xsd" and be included by "xul.xsd" as well. so it is cyclic.

In this file, someone can add his own tags. In there, we also have a group called "customElements". So the schema could look like this:

<xs:schema    targetNamespace="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
            xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
            xmlns:xs="http://www.w3.org/2001/XMLSchema"
            elementFormDefault="qualified">

    <xs:include schemaLocation="xul.xsd" />

    <xs:element name="mycustomelement" type="boxElementType">
        <xs:annotation>
            <xs:documentation source="Link">
                Describes MyCustomElement
            </xs:documentation>
        </xs:annotation>
    </xs:element>

    <xs:group name="customElements">
        <xs:choice>
            <xs:element ref="mycustomelement" minOccurs="0" maxOccurs="unbounded" />
        </xs:choice>
    </xs:group>

</xs:schema>

(sorry for the linebreaks. that's codeplex)

Then, all we have to do in "xul.xsd" is to add the group "customElements" to the group "elementsForBox".

It is not perfect of course, but that is the basic idea. Keeps custom elements and basic xul seperated, so that the "xul.xsd" doesn't have to be changed and can thus safely be updated. As you have more experience with schemas, you probably see some problems with it, that I don't see.

Cheers!
Coordinator
Apr 8, 2009 at 3:26 PM
I'm not sure what you want to achieve, can you post some sample XML?
If it is XBL you want to support you have to create XBL schema, at least I don't know if there is other way to have code completion support.
Creating XBL schema should not be that difficult though.
Are there any other schema that would be of interest?
Apr 8, 2009 at 3:42 PM
Edited Apr 8, 2009 at 3:44 PM
nope. it is not about xbl directly. there is already a nice working xbl schema at http://mozilla.doslash.org/xblschema/

it is more for custom elements. see the following

<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
   <hbox>
       <button label="aButton" />
       <mycustomelement>
              <button label="anotherButton" />
       </mycustomelement>
       <myspecialbutton label="Button with special functionality created in XBL" />
   </hbox>
</window>
 
all native xul-types, like button, box, etc. are written in xbl as well. thus you can also add your own xul elements, like the custom element in the example above. with the current implementation of your xul schema, you would get a warning when you insert such an element into your xul and it would not be in the intellisense.

that's what my change is for. :)

Is it clear now?


Coordinator
Apr 8, 2009 at 3:58 PM
Yes, I understand now.
I know how to handle the validation part, however I'm not sure how to get code completion to work.
Actually it could be done similarly how I did it for HTML, but that one will probably work with Visual Studio only, and will probably get really messy with more additions.
Anyway I will investigate it to see whether there are any simple ways to do it.
Will post findings here.
Coordinator
Apr 8, 2009 at 3:59 PM
This discussion has been copied to a work item. Click here to go to the work item and continue the discussion.
Apr 8, 2009 at 7:07 PM
Well. the intellisense / autocompletion actually works the way I described it with the additional schema-file for custom elements.
Do you see any problem with my implementation? i just ask, because i - as already said - don't know that much about xml schemas and would like to learn from my mistakes if there are some. :)

greetings

p.s. i thought i better add it to the discussion here to have everything at the same place
Coordinator
Apr 11, 2009 at 3:06 PM
I'm going through some options to see what's the best path to take.
One of the options is what you're describing, but it has one shortcoming and that is: you have to change original xul.xsd. The file shouldn't be required to change so I am looking at possibilities of workaround. One of the options is redefine tag - similar to what I'm using for xulXhtml.xsd. I'll add a page with explanation how to extend the schema once I'm happy with approach.
Coordinator
Apr 11, 2009 at 11:57 PM
This is the approach I would recommend at this time:

<xs:schema    targetNamespace="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
            xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
            xmlns:xs="http://www.w3.org/2001/XMLSchema"
            elementFormDefault="qualified">

  <xs:redefine schemaLocation="xul.xsd">
    <xs:group name="boxElementElementsOnlyGroup">
      <xs:choice>
        <xs:group ref="boxElementElementsOnlyGroup" />
        <xs:element ref="mycustomelement" />
      </xs:choice>
    </xs:group>
  </xs:redefine>
 
    <xs:element name="mycustomelement">
      <xs:complexType>
        <xs:group ref="boxElementElementsOnlyGroup" />
        <xs:attributeGroup ref="xulElementAttributes" />
      </xs:complexType>
    </xs:element>

</xs:schema>

Using redefine there is no need to change original xul.xsd schema. One downside of redefine is you can use it only once so if you have more custom elements you have to put them all in one file or to split them and put redefine in one of them. Something like this:

file test1.xsd

<xs:schema    targetNamespace="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
            xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
            xmlns:xs="http://www.w3.org/2001/XMLSchema"
            elementFormDefault="qualified">

  <xs:include schemaLocation="test2.xsd" />

  <xs:redefine schemaLocation="xul.xsd">
    <xs:group name="boxElementElementsOnlyGroup">
      <xs:choice>
        <xs:group ref="boxElementElementsOnlyGroup" />
        <xs:element ref="mycustomelement" />
        <xs:element ref="mycustomelement2" />
      </xs:choice>
    </xs:group>
  </xs:redefine>
 
    <xs:element name="mycustomelement">
      <xs:complexType>
        <xs:group ref="boxElementElementsOnlyGroup" />
        <xs:attributeGroup ref="xulElementAttributes" />
      </xs:complexType>
    </xs:element>

</xs:schema>

file test2.xsd

<xs:schema    targetNamespace="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
            xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
            xmlns:xs="http://www.w3.org/2001/XMLSchema"
            elementFormDefault="qualified">

  <xs:include schemaLocation="xul.xsd" />

  <xs:element name="mycustomelement2">
    <xs:complexType>
      <xs:group ref="boxElementElementsOnlyGroup" />
      <xs:attributeGroup ref="xulElementAttributes" />
    </xs:complexType>
  </xs:element>

</xs:schema>

Or have elements defined in multiple files and have one file that includes them all and does redefine. Something like this:

test1.xsd

<xs:schema    targetNamespace="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
            xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
            xmlns:xs="http://www.w3.org/2001/XMLSchema"
            elementFormDefault="qualified">

  <xs:include schemaLocation="xul.xsd" />

    <xs:element name="mycustomelement">
      <xs:complexType>
        <xs:group ref="boxElementElementsOnlyGroup" />
        <xs:attributeGroup ref="xulElementAttributes" />
      </xs:complexType>
    </xs:element>

</xs:schema>


test2.xsd

<xs:schema    targetNamespace="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
            xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
            xmlns:xs="http://www.w3.org/2001/XMLSchema"
            elementFormDefault="qualified">

  <xs:include schemaLocation="xul.xsd" />

  <xs:element name="mycustomelement2">
    <xs:complexType>
      <xs:group ref="boxElementElementsOnlyGroup" />
      <xs:attributeGroup ref="xulElementAttributes" />
    </xs:complexType>
  </xs:element>

</xs:schema>

redefinexul.xsd

<xs:schema    targetNamespace="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
            xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
            xmlns:xs="http://www.w3.org/2001/XMLSchema"
            elementFormDefault="qualified">

  <xs:include schemaLocation="test1.xsd" />
  <xs:include schemaLocation="test2.xsd" />

  <xs:redefine schemaLocation="xul.xsd">
    <xs:group name="boxElementElementsOnlyGroup">
      <xs:choice>
        <xs:group ref="boxElementElementsOnlyGroup" />
        <xs:element ref="mycustomelement" />
        <xs:element ref="mycustomelement2" />
      </xs:choice>
    </xs:group>
  </xs:redefine>

</xs:schema>

The first approach is good if you have only few elements. If things get more complicated and you have many custom elements that are easier to keep in separate files I would personally use the third approach.

Hope this helps.
Apr 12, 2009 at 1:29 PM
That idea is of course more suitable. Didn't know of a redefine, but its perfect for the situation. Got some trouble first, as VS didn't accept the redefine element, but that was just because it was still placed after other element and group definitions, because i just altered my previous file. Now it works perfectly.

We should add this to the wiki and link it on the mainpage.

Thank you! :)