Element order issue when validating with DTD

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • Dormilich
    Recognized Expert Expert
    • Aug 2008
    • 8694

    Element order issue when validating with DTD

    Hello,

    I'm trying to validate my XML files against a DTD with PHP 5 and it spits out element order errors (see below). the files validate in FF (once I set the used entities in the local DTD part, but that's a FF issue not applying to PHP). From a simpler DTD I know that element order must be the same in DTD and XML but I don't know what the cause is for error 1 (once you leave out the optional elements, it looks the same to me, even the order).

    the other issue is that the nested construct seems not to be recognized by libxml somehow.

    can anyone help me here?

    thanks

    Error messages:
    Code:
    Warning: DOMDocument::load() [function.DOMDocument-load]: 
    Element seite content does not follow the DTD, expecting (titel , datei? , 
    subsection? , preview? , verzeichnis? , bild* , link:author? , link:appendix* , 
    […shortened for readability…] , dcterms:subject? , dcterms:title? , dcterms:type?), 
    got (titel datei dcterms:date dcterms:modified dcterms:title ) 
    in /var/www/kbl/system/xml/main.struktur.xml, line: 17 in /var/www/kbl/test.php on line 5
    and
    Code:
    Warning: DOMDocument::load() [function.DOMDocument-load]: 
    Content model of datei is not determinist: (file | (file? , xsl , xml? , par?)) 
    in /var/www/kbl/system/xml/main.struktur.xml, line: 13 
    in /var/www/kbl/test.php on line 5
    PHP code:
    Code:
    $xml = new DOMDocument("1.0", "iso-8859-1");
    $xml->validatOnParse = true;
    $options = LIBXML_DTDLOAD|LIBXML_DTDATTR|LIBXML_DTDVALID;
    $test = $xml->load("system/xml/main.struktur.xml", $options);
    XML code (snippet, line numbers preserved)
    Code:
    <?xml version="1.0" encoding="iso-8859-1" ?>
    <!-- project control file -->
    <!DOCTYPE kbl SYSTEM "../dtd/struktur.dtd">
    <kbl
        xmlns="http://www.kulturbeutel-leipzig.net/XML/struktur"
        xmlns:link="http://www.kulturbeutel-leipzig.net/XML/link"
        xmlns:dcterms="http://purl.org/dc/terms/">
    
    <seite id="home" title="Startseite">
      <titel>Startseite</titel>
      <datei>
        <file>home.php</file>
      </datei>
      <dcterms:date dc="yes">2008-04-15T08:45+02:00</dcterms:date>
      <dcterms:modified>2008-09-18T10:55+02:00</dcterms:modified>
      <dcterms:title dc="yes">Startseite</dcterms:title>
    </seite>
    
    <seite id="spielplan" title="Spielplan" cssid="spielplan">
      <titel>Auftrittstermine</titel>
      <datei>
        <xml>spielplan.xml</xml>
        <xsl>main.spielplan.xsl</xsl>
        <par>jahr</par>
      </datei>
      <dcterms:title dc="yes">Auftrittstermine</dcterms:title>
      <dcterms:modified>2008-09-18T10:55+02:00</dcterms:modified>
      <dcterms:date dc="yes">2008-04-15T08:45+02:00</dcterms:date>
    </seite>
    
    […]
    
    </kbl>
  • pbmods
    Recognized Expert Expert
    • Apr 2007
    • 5821

    #2
    Heya, Dormilich.

    What's the DTD look like?

    Comment

    • Dormilich
      Recognized Expert Expert
      • Aug 2008
      • 8694

      #3
      that's the DTD
      Code:
      <!ENTITY % latin1 SYSTEM "../dtd/xhtml-lat1.ent">
      %latin1;
      <!ENTITY % metalink SYSTEM "../dtd/dtd.meta.ent">
      %metalink;
      <!ENTITY % relnavi SYSTEM "../dtd/dtd.link.ent">
      %relnavi;
      <!ENTITY % dcmi SYSTEM "../dtd/dtd.dublincore.ent">
      %dcmi;
      
      <!ELEMENT kbl           (seite+)>
      <!ATTLIST kbl
          xmlns               CDATA   #REQUIRED
          xmlns:dcterms       CDATA   #IMPLIED
          xmlns:link          CDATA   #IMPLIED
      >
      <!ELEMENT seite         (titel, datei?, subsection?, preview?, verzeichnis?, bild*, %link.navi;, %dublin.core;)>
      
      <!ATTLIST seite 
          id                  ID      #REQUIRED
          title               CDATA   #REQUIRED
          cssid               CDATA   #IMPLIED
      >
      <!ELEMENT titel         (#PCDATA)>
      
      <!ELEMENT datei         (file | (file?, xsl, xml?, par?))>
      
      <!ELEMENT file          (#PCDATA)>
      <!ATTLIST file 
          base                CDATA   #IMPLIED
      >
      <!ELEMENT xml           (#PCDATA)>
      
      <!ELEMENT xsl           (#PCDATA)>
      
      <!ELEMENT par           (#PCDATA)>
      
      <!ELEMENT subsection    (seite+ | (seite*, collection+))>
      
      <!ELEMENT collection    (titel, subsection+)>
      <!ATTLIST collection 
          id                  ID      #REQUIRED
          title               CDATA   #REQUIRED
      >
      <!ELEMENT verzeichnis   (#PCDATA)>
      
      <!ELEMENT bild          EMPTY>
      <!ATTLIST bild
          id                  CDATA   #IMPLIED
          src                 CDATA   #REQUIRED
          title               CDATA   #REQUIRED
          hgt                 CDATA   #REQUIRED
          wdt                 CDATA   #REQUIRED
      >
      <!ELEMENT preview       (bild | (bild?, longdesc))>
      
      <!ELEMENT longdesc      (#PCDATA)>
      dtd.dublincore. ent - the DCMI entities
      Code:
      <!ELEMENT dcterms:abstract              (#PCDATA)>
      <!ELEMENT dcterms:accessRights          (#PCDATA)>
      <!ELEMENT dcterms:accrualMethod         (#PCDATA)>
      <!ELEMENT dcterms:accrualPeriodicity    (#PCDATA)>
      <!ELEMENT dcterms:accrualPolicy         (#PCDATA)>
      <!ELEMENT dcterms:alternative           (#PCDATA)>
      <!ELEMENT dcterms:audience              (#PCDATA)>
      <!ELEMENT dcterms:available             (#PCDATA)>
      [‒and all the other dcmi elements‒]
      <!ELEMENT dcterms:tableOfContents       (#PCDATA)>
      <!ELEMENT dcterms:temporal              (#PCDATA)>
      <!ELEMENT dcterms:title                 (#PCDATA)>
      <!ELEMENT dcterms:type                  (#PCDATA)>
      <!ELEMENT dcterms:valid                 (#PCDATA)>
      
      <!ATTLIST dcterms:contributor dc (yes|no)  "no">
      <!ATTLIST dcterms:coverage    dc (yes|no)  "no">
      <!ATTLIST dcterms:creator     dc (yes|no)  "no">
      <!ATTLIST dcterms:date        dc (yes|no)  "no">
      <!ATTLIST dcterms:description dc (yes|no)  "no">
      <!ATTLIST dcterms:format      dc (yes|no)  "no">
      <!ATTLIST dcterms:identifier  dc (yes|no)  "no">
      <!ATTLIST dcterms:language    dc (yes|no)  "no">
      <!ATTLIST dcterms:publisher   dc (yes|no)  "no">
      <!ATTLIST dcterms:relation    dc (yes|no)  "no">
      <!ATTLIST dcterms:rights      dc (yes|no)  "no">
      <!ATTLIST dcterms:source      dc (yes|no)  "no">
      <!ATTLIST dcterms:subject     dc (yes|no)  "no">
      <!ATTLIST dcterms:title       dc (yes|no)  "no">
      <!ATTLIST dcterms:type        dc (yes|no)  "no">
      dtd.link.ent - link entity definition
      Code:
      <!ELEMENT link:appendix (#PCDATA)>
      <!ATTLIST link:appendix title   CDATA   #REQUIRED>
         
      <!ELEMENT link:author   (#PCDATA)>
      <!ATTLIST link:author   title   CDATA   #REQUIRED>
      
      <!ELEMENT link:contents (#PCDATA)>
      <!ATTLIST link:contents title   CDATA   #REQUIRED>
      
      <!ELEMENT link:chapter (#PCDATA)>
      <!ATTLIST link:chapter title   CDATA   #REQUIRED>
      
      <!ELEMENT link:section (#PCDATA)>
      <!ATTLIST link:section title   CDATA   #REQUIRED>
      
      <!ELEMENT link:subsection (#PCDATA)>
      <!ATTLIST link:subsection title   CDATA   #REQUIRED>
      
      <!ELEMENT link:index (#PCDATA)>
      <!ATTLIST link:index title   CDATA   #REQUIRED>
      
      <!ELEMENT link:glossary (#PCDATA)>
      <!ATTLIST link:glossary title   CDATA   #REQUIRED>
      
      <!ELEMENT link:copyright (#PCDATA)>
      <!ATTLIST link:copyright title   CDATA   #REQUIRED>
      
      <!ELEMENT link:help (#PCDATA)>
      <!ATTLIST link:help title   CDATA   #REQUIRED>
      
      <!ELEMENT link:bookmark (#PCDATA)>
      <!ATTLIST link:bookmark title   CDATA   #REQUIRED>
      dtd.meta.ent
      Code:
      <!ENTITY % link.navi   "link:author?, 
                              link:appendix*, 
                              link:contents?, 
                              link:chapter*, 
                              link:section*, 
                              link:subsection*, 
                              link:index?, 
                              link:glossary?, 
                              link:copyright?, 
                              link:help?, 
                              link:bookmark*"
      >
      <!ENTITY % dublin.core "dcterms:contributor*, 
                              dcterms:coverage?, 
                              dcterms:creator*, 
                              dcterms:date?, 
                              dcterms:description?, 
                              dcterms:format?, 
                              dcterms:identifier?, 
                              dcterms:language?, 
                              dcterms:publisher*, 
                              dcterms:relation*, 
                              dcterms:rights?, 
                              dcterms:source?, 
                              dcterms:subject?, 
                              dcterms:title?, 
                              dcterms:type?"
      >
      Last edited by Dormilich; Dec 2 '08, 09:18 AM. Reason: added Entity definitions

      Comment

      • pbmods
        Recognized Expert Expert
        • Apr 2007
        • 5821

        #4
        Just in case Firefox is being crazy, I'm going to go ahead and move this thread to the XML forum for a bit and have our XML experts weigh in.

        Comment

        • Dormilich
          Recognized Expert Expert
          • Aug 2008
          • 8694

          #5
          Originally posted by pbmods
          Just in case Firefox is being crazy, I'm going to go ahead and move this thread to the XML forum for a bit and have our XML experts weigh in.
          well yes, but FF doesn't play a role in the problem..... maybe jkmyoung does know anything that can help. but to me it seemed like a problem DOMDocument has with validation/DTDs.
          maybe I have to switch to relaxng or xml schema to get it working.

          Comment

          • jkmyoung
            Recognized Expert Top Contributor
            • Mar 2006
            • 2057

            #6
            Only thing I've noticed so far is that the xml and xsl nodes are out of order here:
            [code=xml]
            # <datei>
            # <xml>spielplan. xml</xml>
            # <xsl>main.spiel plan.xsl</xsl>
            # <par>jahr</par>
            # </datei>
            [/code]

            Comment

            • jkmyoung
              Recognized Expert Top Contributor
              • Mar 2006
              • 2057

              #7
              Sorry, but my dtd is not great so I'm speaking in terms of xml schema. Once you find the file element, the parser doesn't know which branch to take. You need to restructure the dtd so the choice of branches depends on the first element.
              What you have now:
              [code=xml]
              <xs:element name="datei">
              <xs:complexType >
              <xs:choice>
              <xs:element name="file"/>
              <xs:sequence>
              <xs:element name="file" minOccurs="0"/>
              <xs:element name="xsl"/>
              <xs:element name="xml" minOccurs="0"/>
              <xs:element name="par" minOccurs="0"/>
              </xs:sequence>
              </xs:choice>
              </xs:complexType>
              </xs:element>
              [/code]
              What you need to have:
              [code=xml]
              <xs:element name="datei">
              <xs:annotatio n>
              <xs:documentati on>Comment describing your root element</xs:documentatio n>
              </xs:annotation>
              <xs:complexType >
              <xs:choice>
              <xs:sequence>
              <xs:element name="file"/>
              <xs:sequence minOccurs="0">
              <xs:element name="xsl"/>
              <xs:element name="xml" minOccurs="0"/>
              <xs:element name="par" minOccurs="0"/>
              </xs:sequence>
              </xs:sequence>
              <xs:sequence>
              <xs:element name="xsl"/>
              <xs:element name="xml" minOccurs="0"/>
              <xs:element name="par" minOccurs="0"/>
              </xs:sequence>
              </xs:choice>
              </xs:complexType>
              </xs:element>
              [/code]
              The first choice has the file element, the 2nd does not. The nested sequence in the first choice is conditional as well, representing what happens when there is only the file element.
              Note that the xsl part comes in a sequence, so you can't have just xml or par elements by themselves without the xsl element.

              Comment

              • Dormilich
                Recognized Expert Expert
                • Aug 2008
                • 8694

                #8
                Originally posted by jkmyoung
                Only thing I've noticed so far is that the xml and xsl nodes are out of order here:
                for me the element order doesn't matter, but obviously for the validator.... (it seem to choke on the OR operator) would you recommend me switching to XML Schema?

                Comment

                • jkmyoung
                  Recognized Expert Top Contributor
                  • Mar 2006
                  • 2057

                  #9
                  Changing to regexp form:
                  Current:
                  (file | (file?, xsl, xml?, par?))

                  Suggested change:
                  ((file, (xsl, xml?, par?)?) | (xsl, xml?, par?))

                  Sorry, I didn't write it in RE in the first place.

                  Comment

                  • Dormilich
                    Recognized Expert Expert
                    • Aug 2008
                    • 8694

                    #10
                    thanks jkmyoung, it's working. if I order the elements it should resolve the element order warnings too.

                    if I should switch someday to XML Schema, is there something like element order too? (I hope not)

                    regards, Dormi

                    Comment

                    • jkmyoung
                      Recognized Expert Top Contributor
                      • Mar 2006
                      • 2057

                      #11
                      By default, most of the structures use element order. The only ones I can remember which don't are xsd:all or xsd:choice.
                      Of course, you can always use an unbounded sequence with all optional elements, for any ordering and number of elements.

                      Comment

                      • Dormilich
                        Recognized Expert Expert
                        • Aug 2008
                        • 8694

                        #12
                        I'll bear that in mind.

                        Comment

                        Working...