«

»

Oct
25

Creating schema for self-referencing xml file.

Previously I posted on something related to primary key and foreign key used in schema to maintain the relationship for my xml documents. I am still trying to sort that problem out :X
I moved on to try to create a schema for my nested menu. It takes me quite sometimes to find the correct solution for my schema to validate my xml file. But the time is worth it :D

XML:

<menus xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <menu>
        <menuItem name="Profile" link="" xmlPath="user.xml" xslPath="profile.xsl" title="Profile"/>
        <menu name="Idea" link="" xmlPath="idea/idea.xml" xslPath="idea/idea.xsl" title="Idea" >
            <menuItem name="Post New Idea" link="idea/postNewIdea.php" xmlPath="" xslPath="i" title="Post New Idea" />
            <menuItem name="My Idea" link="" xmlPath="idea/idea.xml" xslPath="idea/myIdea.xsl" title="My Idea" />
        </menu>
        <menuItem name="Comment" link="" xmlPath="comment/comment.xml" xslPath="comment/comment.xsl" title="Comment"/>
        <menuItem name="Customize New Menu" link="../menu/addMenu.php" xmlPath="" xslPath="" title="Customize new Menu"/>
        <menuItem name="Logout" link="../logout.php" title="Logout"/>
    </menu>
</menus>

Schema:

    <xsd:element name="menus">
        <xsd:complexType>
            <xsd:sequence maxOccurs="unbounded">
                <xsd:element ref="menu" minOccurs="0"  />
            </xsd:sequence>
        </xsd:complexType>
    </xsd:element>     
   
    <xsd:element name="menu">
        <xsd:complexType >
            <xsd:sequence minOccurs="0" maxOccurs="unbounded">
                <xsd:element name="menuItem"/> 
                <xsd:element ref="menu" minOccurs="0"/>
            </xsd:sequence>
            <xsd:attribute name="name" type="xsd:string"></xsd:attribute>
            <xsd:attribute name="link" type="xsd:string"></xsd:attribute>
            <xsd:attribute name="xmlPath" type="xsd:string"></xsd:attribute>
            <xsd:attribute name="xslPath" type="xsd:string"></xsd:attribute>
            <xsd:attribute name="title" type="xsd:string"></xsd:attribute> 
        </xsd:complexType> 
    </xsd:element>
   
    <xsd:element name="menuItem">
        <xsd:complexType>
            <xsd:attribute name="name" type="xsd:string"></xsd:attribute>
            <xsd:attribute name="link" type="xsd:string"></xsd:attribute>
            <xsd:attribute name="xmlPath" type="xsd:string"></xsd:attribute>
            <xsd:attribute name="xslPath" type="xsd:string"></xsd:attribute>
            <xsd:attribute name="title" type="xsd:string"></xsd:attribute>
        </xsd:complexType>
    </xsd:element>

Note: I have problem in self-referencing when I try to use menu as my root, then I create a new “menus” root so my “menu” element can perfectly reference to itself. I also tried to use xsd:all or xsd:any but the validator complaining about some item like nested “menu” or “menulist” should not existed. I give up on using both method and just stick to xsd:sequence.

Xsl:

 <xsl:template match="menu">
    <xsl:if test="@name">
        <a href="#blank">
            <div><xsl:attribute name="onclick">xajax_openPage('<xsl:value-of select="./@xmlPath"/>','<xsl:value-of select="./@xslPath"/>', '<xsl:value-of select="./@link"/>', '<xsl:value-of select="./@title"/>')</xsl:attribute>
                    <xsl:value-of select="./@name"/></div></a>
    </xsl:if>
    <table>
        <xsl:for-each select="./child::*">
            <tr><td><xsl:apply-templates select="." />
            </td></tr>
        </xsl:for-each>
      </table>
 </xsl:template>
 
    <xsl:template match="menuItem">
        <a href="#blank">
            <div><xsl:attribute name="onclick">xajax_openPage('<xsl:value-of select="./@xmlPath"/>','<xsl:value-of select="./@xslPath"/>', '<xsl:value-of select="./@link"/>', '<xsl:value-of select="./@title"/>')</xsl:attribute>
            <xsl:value-of select="./@name"/></div></a>
    </xsl:template>

Above xsl is the way I render the document to xHTML. In the xsl document, I render the element recursively.

Permanent link to this article: http://lindaocta.com/?p=14

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>