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:
- the nested entity reference as PUBLIC, not SYSTEM
- has an empty string before the desired SYSTEM identifier
- 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
inXMLWriter::startDTD
. You have to provideNULL
for$publicId
to seeSYSTEM
instead ofPUBLIC
.you're confusing
XMLWriter::writeDTD
withXMLWriter::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">
]>
精彩评论