<p> 它将说明如何外部实体指向处理器来包含和解析其它文档,如何处理 PIs,以及一种确定包含有 PIs 的代码的可信度。</p><p> 能被该范例使用的的 XML 文档(xmltest.xml 和 xmltest2.xml)被列在该范例之后。</p><p> 外部实体范例</p><code><?php<br />$file = "xmltest.xml";<br />function trustedFile($file) {<br /> // only trust local files owned by ourselves<br /> if (!eregi("^([a-z]+)://", $file)<br /> && fileowner($file) == getmyuid()) {<br /> return true;<br /> }<br /> return false;<br />}<br />function startElement($parser, $name, $attribs) {<br /> print "<<font color="#0000cc">$name</font>";<br /> if (sizeof($attribs)) {<br /> while (list($k, $v) = each($attribs)) {<br /> print " <font color="#009900">$k</font>="<font<br /> color="#990000">$v</font>"";<br /> }<br /> }<br /> print ">";<br />}<br />function endElement($parser, $name) {<br /> print "</<font color="#0000cc">$name</font>>";<br />}<br />function characterData($parser, $data) {<br /> print "<b>$data</b>";<br />}<br />function PIHandler($parser, $target, $data) {<br /> switch (strtolower($target)) {<br /> case "php":<br /> global $parser_file;<br /> // If the parsed document is "trusted", we say it is safe<br /> // to execute PHP code inside it. If not, display the code<br /> // instead.<br /> if (trustedFile($parser_file[$parser])) {<br /> eval($data);<br /> } else {<br /> printf("Untrusted PHP code: <i>%s</i>",<br /> htmlspecialchars($data));<br /> }<br /> break;<br /> }<br />}<br />function defaultHandler($parser, $data) {<br /> if (substr($data, 0, 1) == "&" && substr($data, -1, 1) == ";") {<br /> printf('<font color="#aa00aa">%s</font>',<br /> htmlspecialchars($data));<br /> } else {<br /> printf('<font size="-1">%s</font>',<br /> htmlspecialchars($data));<br /> }<br />}<br />function externalEntityRefHandler($parser, $openEntityNames, $base, $systemId,<br /> $publicId) {<br /> if ($systemId) {<br /> if (!list($parser, $fp) = new_xml_parser($systemId)) {<br /> printf("Could not open entity %s at %s<br />", $openEntityNames,<br /> $systemId);<br /> return false;<br /> }<br /> while ($data = fread($fp, 4096)) {<br /> if (!xml_parse($parser, $data, feof($fp))) {<br /> printf("XML error: %s at line %d while parsing entity %s<br />",<br /> xml_error_string(xml_get_error_code($parser)),<br /> xml_get_current_line_number($parser), $openEntityNames);<br /> xml_parser_free($parser);<br /> return false;<br /> }<br /> }<br /> xml_parser_free($parser);<br /> return true;<br /> }<br /> return false;<br />}<br />function new_xml_parser($file) {<br /> global $parser_file;<br /> $xml_parser = xml_parser_create();<br /> xml_parser_set_option($xml_parser, XML_OPTION_CASE_FOLDING, 1);<br /> xml_set_element_handler($xml_parser, "startElement", "endElement");<br /> xml_set_character_data_handler($xml_parser, "characterData");<br /> xml_set_processing_instruction_handler($xml_parser, "PIHandler");<br /> xml_set_default_handler($xml_parser, "defaultHandler");<br /> xml_set_external_entity_ref_handler($xml_parser, "externalEntityRefHandler");<br /> <br /> if (!($fp = @fopen($file, "r"))) {<br /> return false;<br /> }<br /> if (!is_array($parser_file)) {<br /> settype($parser_file, "array");<br /> }<br /> $parser_file[$xml_parser] = $file;<br /> return array($xml_parser, $fp);<br />}<br />if (!(list($xml_parser, $fp) = new_xml_parser($file))) {<br /> die("could not open XML input");<br />}<br />print "<pre>";<br />while ($data = fread($fp, 4096)) {<br /> if (!xml_parse($xml_parser, $data, feof($fp))) {<br /> die(sprintf("XML error: %s at line %d<br />",<br /> xml_error_string(xml_get_error_code($xml_parser)),<br /> xml_get_current_line_number($xml_parser)));<br /> }<br />}<br />print "</pre>";<br />print "parse complete<br />";<br />xml_parser_free($xml_parser);<br />?></code></p>
<p> </p>
<p> xmltest.xml<code><?xml version='1.0'?><br /><!DOCTYPE chapter SYSTEM "/just/a/test.dtd" [<br /><!ENTITY plainEntity "FOO entity"><br /><!ENTITY systemEntity SYSTEM "xmltest2.xml"><br />]><br /><chapter><br /><TITLE>Title &plainEntity;</TITLE><br /><para><br /> <informaltable><br /> <tgroup cols="3"><br /> <tbody><br /> <row><entry>a1</entry><entry morerows="1">b1</entry><entry>c1</entry></row><br /> <row><entry>a2</entry><entry>c2</entry></row><br /> <row><entry>a3</entry><entry>b3</entry><entry>c3</entry></row><br /> </tbody><br /> </tgroup><br /> </informaltable><br /></para><br />&systemEntity;<br /><section id="about"><br /> <title>About this Document</title><br /> <para><br /> <!-- this is a comment --><br /> <?php print 'Hi! This is PHP version '.phpversion(); ?><br /> </para><br /></section><br /></chapter></code><p> 以下文档将被 xmltest.xml 文件调用: xmltest2.xml</p></p>