You can easily avoid the warning about references by using the LIBXML_DTDLOAD option.
<?php
$html = <<<EOF
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
</head>
<body>
<p> </p>
</body>
</html>
EOF;
// This one works perfectly.
$dom = new DOMDocument();
$dom->loadXML($html, LIBXML_DTDLOAD);
print $dom->saveXML();
// This one produces a warning.
$dom = new DOMDocument();
$dom->loadXML($html);
print $dom->saveXML();
?>
See also: http://www.php.net/manual/en/libxml.constants.php
Note that libxml will detect that your DTD is locally available via /etc/xml/catalog. So there is no worry about this causing your DOM loads to make external network requests.
DOMDocument::load
(PHP 5)
DOMDocument::load — ファイルから XML を読み込む
説明
XML ドキュメントをファイルから読み込みます。
警告
Unix 風のパス (スラッシュを使った方式) を Windows 上で使用すると、 パフォーマンスが著しく低下します。そんな場合は realpath() をコールしましょう。
返り値
成功した場合に TRUE を、失敗した場合に FALSE を返します。 静的にコールされた場合には DOMDocument を返し、 E_STRICT 警告を発生させます。
エラー / 例外
空の文字列を filename に渡したり中身が空のファイルを指定したりすると、警告が発生します。 この警告は libxml が発するものではないので、libxml のエラー処理関数では処理できません。
例
例1 ドキュメントの作成
<?php
$doc = new DOMDocument();
$doc->load('book.xml');
echo $doc->saveXML();
?>
参考
- DOMDocument::loadXML - 文字列から XML を読み込む
- DOMDocument::save - 内部の XML ツリーをファイルに出力する
- DOMDocument::saveXML - 内部の XML ツリーを文字列として出力する
DOMDocument::load
zachatwork at gmail dot com
01-Jul-2009 06:28
01-Jul-2009 06:28
Jonas Due Vesterheden
09-Jun-2009 03:18
09-Jun-2009 03:18
I had a problem with loading documents over HTTP. I would get errors looking like this:
Warning: DOMDocument::load(http://external/document.xml): failed to open stream: HTTP request failed! HTTP/1.1 500 Internal Server Error
The document would load fine in browsers and using wget. The problem is that DOMDocument::load() on my systems (both OS X and Linux) didn't send any User-Agent header which for some weird reason made Microsoft-IIS/6.0 respond with the 500 error.
The solution is found on http://php.net/manual/en/function.libxml-set-streams-context.php :
<?php
$opts = array(
'http' => array(
'user_agent' => 'PHP libxml agent',
)
);
$context = stream_context_create($opts);
libxml_set_streams_context($context);
// request a file through HTTP
$doc = DOMDocument::load('http://www.example.com/file.xml');
?>
darren at viamedia dot co dot za
05-Aug-2008 02:17
05-Aug-2008 02:17
If you are loading xml with the intention of validating it against an internal dtd and you have experienced issues with the validation it could be related to missing LIBXML constants.
I found this post by "aidan at php dot net" in root level dom docs and thought it might be more useful here:
As of PHP 5.1, libxml options may be set using constants rather than the use of proprietary DomDocument properties.
DomDocument->resolveExternals is equivilant to setting
LIBXML_DTDLOAD
LIBXML_DTDATTR
DomDocument->validateOnParse is equivilant to setting
LIBXML_DTDLOAD
LIBXML_DTDVALID
PHP 5.1 users are encouraged to use the new constants.
Example:
<?php
$dom = new DOMDocument;
// Resolve externals
$dom->load($file, LIBXML_DTDLOAD|LIBXML_DTDATTR);
// OR
// Validate against DTD
$dom->load($file, LIBXML_DTDLOAD|LIBXML_DTDVALID);
$dom->validate();
?>
the_N_Channel
15-Jul-2008 11:53
15-Jul-2008 11:53
NOTE, will not load successfully if there is a comment at the beginning of the file before the <?xml version="1.0" ?> declaration!
hh dot lohmann at yahoo dot de
30-Aug-2007 10:48
30-Aug-2007 10:48
BadGuy´s note may be confusing since what he depicts is no special property of the relevant method. PHP works always in and on a local file system which means that if you want to use resources from other systems or - what is, indeed, BadGuy´s problem - need resources that have been dealt with by other programs or processes, you have to state and manage that explicitly in your code. PHP is just a quite normal program in that.
BadGuy´s solution is using the "http wrapper" to get output from another process (see "wrappers" in the PHP manual). Doing this, the appropriate syntax for http calls has to be respected.
admin at tijnema dot tijnema dot info
02-Jun-2007 11:39
02-Jun-2007 11:39
In reply to BadGuy [at] BadGuy [dot] nl
When the news.php file is located on the same server, like you said in the first example then http://my.beautiful-website.com/xmlsource/news.php wouldn't work, but you should use http://localhost/xmlsource/news.php or http://127.0.0.1/xmlsource/news.php
BadGuy [at] BadGuy [dot] nl
18-Jan-2007 04:50
18-Jan-2007 04:50
Note that this method uses the local file system before doing anything remote. The 'disadvantage' would be that if you would do the following:
<?php
$xml = new DOMDocument;
$xml->load("xmlsource/news.php");
?>
This would not make the method read the actual output of the news.php file --presumably valid xml data--, but the file contents --obviously this would be php code. So this will return an error saying news.php is missing the xml declaration and maybe the xml start-tag
What would work is the following:
<?php
$xml = new DOMDocument;
$xml->load("http://my.beautiful-website.com/xmlsource/news.php");
?>
This will force a http request to be used to get this file instead of just locally reading it and the file just returning code
daevid at daevid dot com
19-Oct-2005 12:08
19-Oct-2005 12:08
Suppose you wanted to dynamically load an array from an .XSD file. This method is your guy. just remember to use the actual xs: portion in xpaths and such.
All the other "load" methods will error out.
<?php
$attributes = array();
$xsdstring = "/htdocs/api/xsd/common.xsd";
$XSDDOC = new DOMDocument();
$XSDDOC->preserveWhiteSpace = false;
if ($XSDDOC->load($xsdstring))
{
$xsdpath = new DOMXPath($XSDDOC);
$attributeNodes =
$xsdpath->
query('//xs:simpleType[@name="attributeType"]')
->item(0);
foreach ($attributeNodes->childNodes as $attr)
{
$attributes[ $attr->getAttribute('value') ] = $attr->getAttribute('name');
}
unset($xsdpath);
}
print_r($attributes);
?>
