Dalszy ciąg zmagań z przygotowaniem nietypowej schemy.
Zastrzeżenia
- Tekst nie jest poradnikiem pisania schem. Artykuł - w zamierzeniach - ma pokazać ich dość specyficzne zastosowanie.
- Materiał jest pierwszym przybliżeniem opisu moich zmagań z zagadnieniem generowania poprawnego, semantycznego HTML'a.
- Na chwilę obecną skupiam się na elementach niegenerujących niuansów (typu : zakaz A w A, zakaz FORM w FORM, INPUT tylko wewnątrz FORM, itp.).
- Na tym etapie nie zajmuję się atrybutami.
Przemilczenia, odstępstwa oraz reinterpretacje popełnione z wyrachowaną premedytacją:
- Dopuszczenie dowolnych atrybutów:
<xs:attributeGroup name="htmlCoreAttsAll">
<xs:anyAttribute processContents="skip"/> - Uproszczenie struktury HEAD.
- Zmiana kolejności wystąpień w MAP:
- DTD:
((%block;) | AREA)+
- schema:
<xs:choice maxOccurs="unbounded">
<xs:element ref="AREA"/>
<xs:group ref="htmlBlockAll"/>
- DTD:
Struktura pierwszego przybliżenia schemy
Na potrzeby określania zawartości elementów utworzonych zostało pięć nazwanych typów złożonych:
- Zawartość pusta - htmlEmptyContent - elementy typu: IMG, HR, BR.
- Zawartość tekstowa - htmlTextContent - elementy typu: TITLE, OPTION, TEXTAREA.
- Zawartość inline - htmlInlineContent - elementy typu: A, B, SPAN (ale również P i H1 - H6).
- Zawartość block - htmlBlockContent - elementy typu: FORM, BLOCKQUOTE.
- Zawartość (no właśnie, jaka?) - htmlFlowContent -elementy typu: DIV, LI, TD.
Elementy z zawartością niestandardową określone zostały przez typy złożone wbudowane (np. OL, LI, TABLE).
Definicje grup - według html'owego DTD (4.01 Strict).
Po co taka schema?
Mi, na co dzień, bardzo podobna schema pomaga w:
- Pisaniu "z palca" kawałków xml'owej reprezentacji HTML'a w Visual Studio.
- Zamykaniu (w tej samej xml'owej reprezentacji) na krótko pustych elementów.
- Analizie obcych html'i (a konkretnie typowaniu miejsc zakończenia niezamkniętych P, rozgryzania skrzyżowanych elementów i wyłapywania błędów w zagnieżdżeniach).
<?xml version="1.0" encoding="UTF-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xs:attributeGroup name="htmlCoreAttsAll"> <xs:anyAttribute processContents="skip"/> </xs:attributeGroup> <xs:complexType name="htmlEmptyContent"> <xs:attributeGroup ref="htmlCoreAttsAll"/> </xs:complexType> <xs:complexType name="htmlTextContent" mixed="true"> <xs:attributeGroup ref="htmlCoreAttsAll"/> </xs:complexType> <xs:complexType name="htmlInlineContent" mixed="true"> <xs:choice minOccurs="0" maxOccurs="unbounded"> <xs:group ref="htmlInlineAll"/> </xs:choice> <xs:attributeGroup ref="htmlCoreAttsAll"/> </xs:complexType> <xs:complexType name="htmlBlockContent"> <xs:choice minOccurs="0" maxOccurs="unbounded"> <xs:group ref="htmlBlockAll"/> </xs:choice> <xs:attributeGroup ref="htmlCoreAttsAll"/> </xs:complexType> <xs:complexType name="htmlFlowContent" mixed="true"> <xs:choice minOccurs="0" maxOccurs="unbounded"> <xs:group ref="htmlFlowAll"/> </xs:choice> <xs:attributeGroup ref="htmlCoreAttsAll"/> </xs:complexType> <xs:group name="htmlHeadMiscAll"> <xs:choice> <xs:element ref="SCRIPT"/> <xs:element ref="STYLE"/> <xs:element ref="META"/> <xs:element ref="LINK"/> <xs:element ref="OBJECT"/> </xs:choice> </xs:group> <xs:group name="htmlHeadingAll"> <xs:choice> <xs:element ref="H1"/> <xs:element ref="H2"/> <xs:element ref="H3"/> <xs:element ref="H4"/> <xs:element ref="H5"/> <xs:element ref="H6"/> </xs:choice> </xs:group> <xs:group name="htmlListAll"> <xs:choice> <xs:element ref="UL"/> <xs:element ref="OL"/> </xs:choice> </xs:group> <xs:group name="htmlPreformattedAll"> <xs:choice> <xs:element name="PRE"/> </xs:choice> </xs:group> <xs:group name="htmlFontstyleAll"> <xs:choice> <xs:element ref="TT"/> <xs:element ref="I"/> <xs:element ref="B"/> <xs:element ref="BIG"/> <xs:element ref="SMALL"/> </xs:choice> </xs:group> <xs:group name="htmlPhraseAll"> <xs:choice> <xs:element ref="EM"/> <xs:element ref="STRONG"/> <xs:element ref="DFN"/> <xs:element ref="CODE"/> <xs:element ref="SAMP"/> <xs:element ref="KBD"/> <xs:element ref="VAR"/> <xs:element ref="CITE"/> <xs:element ref="ABBR"/> <xs:element ref="ACRONYM"/> </xs:choice> </xs:group> <xs:group name="htmlSpecialAll"> <xs:choice> <xs:element ref="A"/> <xs:element ref="IMG"/> <xs:element ref="OBJECT"/> <xs:element ref="BR"/> <xs:element ref="SCRIPT"/> <xs:element ref="MAP"/> <xs:element ref="Q"/> <xs:element ref="SUB"/> <xs:element ref="SUP"/> <xs:element ref="SPAN"/> <xs:element ref="BDO"/> </xs:choice> </xs:group> <xs:group name="htmlFormctrlAll"> <xs:choice> <xs:element ref="INPUT"/> <xs:element ref="SELECT"/> <xs:element ref="TEXTAREA"/> <xs:element ref="LABEL"/> <xs:element ref="BUTTON"/> </xs:choice> </xs:group> <xs:group name="htmlInlineAll"> <xs:choice> <xs:group ref="htmlFontstyleAll"/> <xs:group ref="htmlPhraseAll"/> <xs:group ref="htmlSpecialAll"/> <xs:group ref="htmlFormctrlAll"/> </xs:choice> </xs:group> <xs:group name="htmlBlockAll"> <xs:choice> <xs:element ref="P"/> <xs:group ref="htmlHeadingAll"/> <xs:group ref="htmlListAll"/> <xs:group ref="htmlPreformattedAll"/> <xs:element ref="DL"/> <xs:element ref="DIV"/> <xs:element ref="NOSCRIPT"/> <xs:element ref="BLOCKQUOTE"/> <xs:element ref="FORM"/> <xs:element ref="HR"/> <xs:element ref="TABLE"/> <xs:element ref="FIELDSET"/> <xs:element ref="ADDRESS"/> </xs:choice> </xs:group> <xs:group name="htmlFlowAll"> <xs:choice> <xs:group ref="htmlBlockAll"/> <xs:group ref="htmlInlineAll"/> </xs:choice> </xs:group> <xs:element name="TT" type="htmlInlineContent"/> <xs:element name="I" type="htmlInlineContent"/> <xs:element name="B" type="htmlInlineContent"/> <xs:element name="BIG" type="htmlInlineContent"/> <xs:element name="SMALL" type="htmlInlineContent"/> <xs:element name="EM" type="htmlInlineContent"/> <xs:element name="STRONG" type="htmlInlineContent"/> <xs:element name="DFN" type="htmlInlineContent"/> <xs:element name="CODE" type="htmlInlineContent"/> <xs:element name="SAMP" type="htmlInlineContent"/> <xs:element name="KBD" type="htmlInlineContent"/> <xs:element name="VAR" type="htmlInlineContent"/> <xs:element name="CITE" type="htmlInlineContent"/> <xs:element name="ABBR" type="htmlInlineContent"/> <xs:element name="ACRONYM" type="htmlInlineContent"/> <xs:element name="SUB" type="htmlInlineContent"/> <xs:element name="SUP" type="htmlInlineContent"/> <xs:element name="SPAN" type="htmlInlineContent"/> <xs:element name="BDO" type="htmlInlineContent"/> <xs:element name="BR" type="htmlEmptyContent"/> <xs:element name="BODY"> <xs:complexType> <xs:choice minOccurs="0" maxOccurs="unbounded"> <xs:group ref="htmlBlockAll"/> <xs:element ref="SCRIPT"/> <xs:element ref="INS"/> <xs:element ref="DEL"/> </xs:choice> <xs:attributeGroup ref="htmlCoreAttsAll"/> </xs:complexType> </xs:element> <xs:element name="ADDRESS" type="htmlInlineContent"/> <xs:element name="DIV" type="htmlFlowContent"/> <xs:element name="A" type="htmlInlineContent"/> <xs:element name="MAP"> <xs:complexType> <xs:sequence maxOccurs="unbounded"> <xs:element ref="AREA"/> <xs:group ref="htmlBlockAll"/> </xs:sequence> <xs:attributeGroup ref="htmlCoreAttsAll"/> </xs:complexType> </xs:element> <xs:element name="AREA" type="htmlEmptyContent"/> <xs:element name="LINK" type="htmlEmptyContent"/> <xs:element name="IMG" type="htmlEmptyContent"/> <xs:element name="OBJECT"> <xs:complexType mixed="true"> <xs:choice minOccurs="0" maxOccurs="unbounded"> <xs:element ref="PARAM"/> <xs:group ref="htmlFlowAll"/> </xs:choice> <xs:attributeGroup ref="htmlCoreAttsAll"/> </xs:complexType> </xs:element> <xs:element name="PARAM" type="htmlEmptyContent"/> <xs:element name="HR" type="htmlEmptyContent"/> <xs:element name="P" type="htmlInlineContent"/> <xs:element name="H1" type="htmlInlineContent"/> <xs:element name="H2" type="htmlInlineContent"/> <xs:element name="H3" type="htmlInlineContent"/> <xs:element name="H4" type="htmlInlineContent"/> <xs:element name="H5" type="htmlInlineContent"/> <xs:element name="H6" type="htmlInlineContent"/> <xs:element name="PRE" type="htmlInlineContent"/> <xs:element name="Q" type="htmlInlineContent"/> <xs:element name="BLOCKQUOTE" type="htmlBlockContent"/> <xs:element name="INS" type="htmlFlowContent"/> <xs:element name="DEL" type="htmlFlowContent"/> <xs:element name="DL"> <xs:complexType> <xs:choice maxOccurs="unbounded"> <xs:element ref="DT"/> <xs:element ref="DD"/> </xs:choice> <xs:attributeGroup ref="htmlCoreAttsAll"/> </xs:complexType> </xs:element> <xs:element name="DT" type="htmlInlineContent"/> <xs:element name="DD" type="htmlFlowContent"/> <xs:element name="OL"> <xs:complexType> <xs:choice maxOccurs="unbounded"> <xs:element ref="LI"/> </xs:choice> <xs:attributeGroup ref="htmlCoreAttsAll"/> </xs:complexType> </xs:element> <xs:element name="UL"> <xs:complexType> <xs:choice maxOccurs="unbounded"> <xs:element ref="LI"/> </xs:choice> <xs:attributeGroup ref="htmlCoreAttsAll"/> </xs:complexType> </xs:element> <xs:element name="LI" type="htmlFlowContent"/> <xs:element name="FORM"> <xs:complexType> <xs:choice maxOccurs="unbounded"> <xs:group ref="htmlBlockAll"/> <xs:element ref="SCRIPT"/> </xs:choice> <xs:attributeGroup ref="htmlCoreAttsAll"/> </xs:complexType> </xs:element> <xs:element name="LABEL" type="htmlInlineContent"/> <xs:element name="INPUT" type="htmlEmptyContent"/> <xs:element name="SELECT"> <xs:complexType> <xs:choice maxOccurs="unbounded"> <xs:element ref="OPTGROUP"/> <xs:element ref="OPTION"/> </xs:choice> <xs:attributeGroup ref="htmlCoreAttsAll"/> </xs:complexType> </xs:element> <xs:element name="OPTGROUP"> <xs:complexType> <xs:choice maxOccurs="unbounded"> <xs:element ref="OPTION"/> </xs:choice> <xs:attributeGroup ref="htmlCoreAttsAll"/> </xs:complexType> </xs:element> <xs:element name="OPTION" type="htmlTextContent"/> <xs:element name="TEXTAREA" type="htmlTextContent"/> <xs:element name="FIELDSET"> <xs:complexType mixed="true"> <xs:choice minOccurs="0" maxOccurs="unbounded"> <xs:element ref="LEGEND"/> <xs:group ref="htmlFlowAll"/> </xs:choice> <xs:attributeGroup ref="htmlCoreAttsAll"/> </xs:complexType> </xs:element> <xs:element name="LEGEND" type="htmlInlineContent"/> <xs:element name="BUTTON" type="htmlFlowContent"/> <xs:element name="TABLE"> <xs:complexType> <xs:sequence> <xs:element ref="CAPTION" minOccurs="0"/> <xs:choice minOccurs="0"> <xs:element ref="COL" maxOccurs="unbounded"/> <xs:element ref="COLGROUP" maxOccurs="unbounded"/> </xs:choice> <xs:element ref="THEAD" minOccurs="0"/> <xs:element ref="TFOOT" minOccurs="0"/> <xs:element ref="TBODY" maxOccurs="unbounded"/> </xs:sequence> <xs:attributeGroup ref="htmlCoreAttsAll"/> </xs:complexType> </xs:element> <xs:element name="CAPTION" type="htmlInlineContent"/> <xs:element name="THEAD"> <xs:complexType> <xs:choice maxOccurs="unbounded"> <xs:element ref="TR"/> </xs:choice> <xs:attributeGroup ref="htmlCoreAttsAll"/> </xs:complexType> </xs:element> <xs:element name="TFOOT"> <xs:complexType> <xs:choice maxOccurs="unbounded"> <xs:element ref="TR"/> </xs:choice> <xs:attributeGroup ref="htmlCoreAttsAll"/> </xs:complexType> </xs:element> <xs:element name="TBODY"> <xs:complexType> <xs:choice maxOccurs="unbounded"> <xs:element ref="TR"/> </xs:choice> <xs:attributeGroup ref="htmlCoreAttsAll"/> </xs:complexType> </xs:element> <xs:element name="COLGROUP"> <xs:complexType> <xs:choice minOccurs="0" maxOccurs="unbounded"> <xs:element ref="COL"/> </xs:choice> <xs:attributeGroup ref="htmlCoreAttsAll"/> </xs:complexType> </xs:element> <xs:element name="COL" type="htmlEmptyContent"/> <xs:element name="TR"> <xs:complexType> <xs:choice maxOccurs="unbounded"> <xs:element ref="TH"/> <xs:element ref="TD"/> </xs:choice> <xs:attributeGroup ref="htmlCoreAttsAll"/> </xs:complexType> </xs:element> <xs:element name="TH" type="htmlFlowContent"/> <xs:element name="TD" type="htmlFlowContent"/> <xs:element name="HEAD"> <xs:complexType> <xs:sequence> <xs:element ref="TITLE" minOccurs="0"/> <xs:element ref="BASE" minOccurs="0" /> <xs:group ref="htmlHeadMiscAll" minOccurs="0" maxOccurs="unbounded"/> </xs:sequence> <xs:attributeGroup ref="htmlCoreAttsAll"/> </xs:complexType> </xs:element> <xs:element name="TITLE" type="htmlTextContent"/> <xs:element name="BASE" type="htmlEmptyContent"/> <xs:element name="META" type="htmlEmptyContent"/> <xs:element name="STYLE" type="htmlTextContent"/> <xs:element name="SCRIPT" type="htmlTextContent"/> <xs:element name="NOSCRIPT" type="htmlBlockContent"/> <xs:element name="HTML"> <xs:complexType> <xs:sequence> <xs:element ref="HEAD"/> <xs:element ref="BODY"/> </xs:sequence> <xs:attributeGroup ref="htmlCoreAttsAll"/> </xs:complexType> </xs:element> </xs:schema>
Dokładniej następnym razem







