开发者

PHP XMLWriter: What parameters do I need to pass to XMLWriter::writeDtdEntity to generate a nested entity DTD declaration as described?

I want to generate a nested entity DTD declaration on top of an XML document with XMLWriter. I started with just string-building code w/o XMLWriter which illustrates the desired output as well:

<?php
$sXML = "<!DOCTYPE Example PUBLIC \"urn:example:example.org:20110823:Example\"\n";
$sXML .= "\"http://www.example.org/example.dtd\" [\n";
$sXML .= "<!ENTITY % nestedentity SYSTEM ";
$sXML .= "\"http://www.example.org/nestedentity.dtd\">\n";
$sXML .= "%nestedentity;\n";
$sXML .= "]>\n";

Current (Desired) $sXML Output:

<!DOCTYPE Example PUBLIC "urn:example:example.org:20110823:Example"
"http://www.example.org/example.dtd" [
<!ENTITY % anentity SYSTEM "http://www.example.org/nestedentity.dtd">
%anentity;
]>

Current XMLWriter $sXML Output (code below):

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Example
PUBLIC "urn:example:example.org:20110823:Example"
       "http://www.example.org/example.dtd" [
        <!ENTITY % anentity PUBLIC "" "http://www.example.org/nestedentity.dtd">
]>

As you can see, the current XMLWriter code XML output has the following issues:

  1. the nested entity reference as PUBLIC, not SYSTEM
  2. has an empty string before the desired SYSTEM identifier
  3. does not inline the entity expansion string, '%anentity;', prior to closing the DOCTYPE declaration.

So, the question is, how do I call $oXMLWriter->writeDtdEntity such that the XML string displayed in the "Current (Desired) $sXML Output" section is displayed (ignoring differences purely in whitespace)?

Current XMLWriter Code:

<?php
$oWriter = new XMLWriter();
$oWriter->openMemory();
$oWriter->setIndent(true);
$oWriter->setIndentString("\t");
$oWriter-&开发者_如何学编程gt;startDocument("1.0", "UTF-8");
$oWriter->startDtd('Example','urn:example:example.org:20110823:Example', 'http://www.example.org/example.dtd');
$oWriter->writeDtdEntity(
    'nestedentity',
    '%nestedentity;\n',
    true,
    null,
    'http://www.example.org/nestedentity.dtd'
);
$oWriter->endDtd();
$oWriter->endDocument();
$sXML = $oWriter->outputMemory();


Well I'm not an expert in DTDs but I notice a couple of mistakes:

  • you provide a value for both $publicId and $systemId in XMLWriter::startDTD. You have to provide NULL for $publicId to see SYSTEM instead of PUBLIC.

  • you're confusing XMLWriter::writeDTD with XMLWriter::writeDTDEntity. The latter only accepts two parameters: the name of the entity and the value of the entity

Just a short example with:

$oWriter = new XMLWriter();
$oWriter->openMemory();
$oWriter->setIndent(true);
$oWriter->setIndentString("\t");
$oWriter->startDocument("1.0", "UTF-8");
    // use null for $publicID to force SYSTEM
    $oWriter->startDtd('Example', null, 'http://www.example.org/example.dtd');
    $oWriter->writeDTDEntity('foo', 'bar');
    $oWriter->endDtd();
$oWriter->endDocument();
$sXML = $oWriter->outputMemory();

And the result is as expected (notice the SYSTEM instead of PUBLIC):

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Example
SYSTEM "http://www.example.org/example.dtd" [
    <!ENTITY foo "bar">
]>
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜