Dooderoo
Dooderoo

Reputation: 229

XML Document Type with internal DTD

The PHP manual includes an example on how to declare an XML Document Type with an attached DTD:

    <?php
    // Creates an instance of the DOMImplementation class
    $imp = new DOMImplementation;

    // Creates a DOMDocumentType instance
    $dtd = $imp->createDocumentType('graph', '', 'graph.dtd');

    // Creates a DOMDocument instance
    $dom = $imp->createDocument("", "", $dtd);

    // Set other properties
    $dom->encoding = 'UTF-8';
    $dom->standalone = false;
    [...]
    ?>

Where graph.dtd would look something like

    <!ELEMENT graph (id,url)>
    <!ELEMENT id (#PCDATA)>
    <!ELEMENT url (#PCDATA)>

The result is an XML header like this:

    <?xml version="1.0" encoding="UTF-8" standalone="no"?>
    <!DOCTYPE graph SYSTEM "graph.dtd">

How can I use DOMImplementation->createDocumentType to create an internal (vs. attached) DTD to get something like this:

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <!DOCTYPE graph [
      <!ELEMENT graph (id,url)>
      <!ELEMENT id (#PCDATA)>
      <!ELEMENT url (#PCDATA)>
    ]>

Update

Workaround by reading the DOCTYPE from an existing file that contains the DTD an no data:

    $doc = new DOMDocument();
    $doc->load('graph.xml');

    //get the actual root element
    $graph=$doc->documentElement; 

    $graph->appendChild($doc->createElement('id','12'));
    $graph->appendChild($doc->createElement('url','foo.png'));      

    echo $doc->saveXML();

Upvotes: 2

Views: 1093

Answers (1)

pozs
pozs

Reputation: 36264

  • You can use data URIs (as suggested here) to embed the content of your DTD into your document,
  • or you can create an empty document, which holds the DTD nodes already, and then instead of creating documents with DOMImplementation, you could just parse this pre-made document as it can hold such data in its internalSubset property, f.ex.:

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <!DOCTYPE graph [
      <!ELEMENT graph (id,url)>
      <!ELEMENT id (#PCDATA)>
      <!ELEMENT url (#PCDATA)>
    ]>
    <graph />
    

Upvotes: 1

Related Questions