simplexml_load_file
(PHP 5, PHP 7, PHP 8)
simplexml_load_file — XMLファイルをパースし、オブジェクトに代入する
説明
string
$filename
,?string
$class_name
= SimpleXMLElement::class,int
$options
= 0,string
$namespace_or_prefix
= "",bool
$is_prefix
= false
): SimpleXMLElement|false
指定したファイルの中の整形式 XML ドキュメントをオブジェクトに変換します。
パラメータ
filename
-
XML ファイルへのパス。
class_name
-
simplexml_load_file() が指定されたクラスのオブジェクトを返すようにするために、 このオプションのパラメータを使用します。 このクラスは、SimpleXMLElement クラスを継承していなければなりません。
options
-
追加の Libxml パラメータ を、ビット演算子の
OR
で指定します。 namespace_or_prefix
-
名前空間プレフィックスあるいは URI。
is_prefix
-
namespace_or_prefix
がプレフィックスである場合にtrue
、 URI である場合にfalse
。デフォルトはfalse
です。
戻り値
SimpleXMLElement クラスのオブジェクトを返します。
XML ドキュメント内のデータをプロパティに含みます。
失敗した場合に false
を返します。
エラー / 例外
XML データ内でエラーが見つかるたびに E_WARNING
エラーメッセージが発生します。
libxml_use_internal_errors() ですべての XML エラーを抑制し、 後から libxml_get_errors() で取得することもできます。
例
例1 XMLドキュメントをパースする
<?php
// The file test.xml contains an XML document with a root element
// and at least an element /[root]/title.
if (file_exists('test.xml')) {
$xml = simplexml_load_file('test.xml');
print_r($xml);
} else {
exit('Failed to open test.xml.');
}
?>
このスクリプトは成功時に以下のように出力します。
SimpleXMLElement Object ( [title] => Example Title ... )
この時点で、$xml->title
としたり、
他の全ての要素にアクセスすることができます。
参考
- simplexml_load_string() - XML 文字列をオブジェクトに代入する
- SimpleXMLElement::__construct() - 新しい SimpleXMLElement オブジェクトを作成する
- XML エラーの対応
- libxml_use_internal_errors() - libxmlエラーを無効にし、ユーザーが必要に応じてエラー情報を取得できるようにする
- 基本的な SimpleXML の使用法
- libxml_set_streams_context() - 次のlibxmlドキュメントの読込/書きこみのためにストリームコンテキストを設定する
User Contributed Notes 30 notes
Sometimes we have xml's with hyphens nodes, like
<my_xml>
<some-node>value</some-node>
</my_xml>
You'll need to use
<?php
$simpleXmlObj->{'some-node'}
?>
instead of
<?php
$simpleXmlObj->some-node;
?>
To correctly extract a value from a CDATA just make sure you cast the SimpleXML Element to a string value by using the cast operator:
<?php
$xml = '<?xml version="1.0" encoding="UTF-8" ?>
<rss>
<channel>
<item>
<title><![CDATA[Tom & Jerry]]></title>
</item>
</channel>
</rss>';
$xml = simplexml_load_string($xml);
// echo does the casting for you
echo $xml->channel->item->title;
// but vardump (or print_r) not!
var_dump($xml->channel->item->title);
// so cast the SimpleXML Element to 'string' solve this issue
var_dump((string) $xml->channel->item->title);
?>
Above will output:
Tom & Jerry
object(SimpleXMLElement)#4 (0) {}
string(11) "Tom & Jerry"
// Be carefull if you migrate or use local machine
// for test/development.
// Windows directory separators: "\" and "/"
// You may mix separators "C:\somedir\www/img/bg.jpg".
// Mixed separators path work fine in other functions
// But simplexml_load_file() failed with mixed separators.
// Examples:
include("C:\dir\my.php"); // work (windows)
include("C:\dir/my.php"); // work (windows) with mixed
include("C:/dir/my.php"); // work (windows, linux)
simplexml_load_file("C:\dir\my.php"); // work
simplexml_load_file("C:\dir/my.php"); // failed with mixed
simplexml_load_file("C:/dir/my.php"); // work
Because the encoding of my XML file is UTF-8 and the
encoding of my web page is iso-8859-1 I was getting strange characters such as ’ instead of a right single quote.
The solution to this turned out to be hard to find, but really easy to implement.
http://uk3.php.net/manual/en/function.iconv.php
Using the iconv() function you can convert from one encodign to another, the TRANSLIT option seems to work best for what I needed. Here's my example:
<?php
// convert string from utf-8 to iso8859-1
$horoscope = iconv( "UTF-8", "ISO-8859-1//TRANSLIT", $horoscope );
?>
I found the solution on this page...
http://tinyurl.com/lm39xc
Hope this helps
This may sometimes get missed, but if your xml nodes are in the format:
<prefix:element />
You need to make sure to set the [namespace or prefix] argument and the [isPrefix] argument to true. Also when recalling elements you need to avoid adding the prefix if that is already set, so in the above example "prefix:element" should be added as "element" but when saved the prefix will be added automatically.
If prefix is not set during load or object construction, load will fail to get the nodes correctly and you will not be able to recall elements directly so $xml->{'prefix:element'} will not work either.
If you want CDATA in your object you should use LIBXML_NOCDATA
<?php
$xml = simplexml_load_file($file_xml, 'SimpleXMLElement',LIBXML_NOCDATA);
print_r($xml);
?>
if you want to check when this function fails,make sure to compare the return value with === instead of == :
<?php
$url = 'http://www.example.com';
$xml = simpleXML_load_file($url,"SimpleXMLElement",LIBXML_NOCDATA);
if($xml === FALSE)
{
//deal with error
}
else { //do stuff }
?>
Otherwise you may end up with FALSE all the time even if the document is ok. Hope this helps someone ;)
LibXML typically uses ten times the file size in memory to read a file, and this memory usage falls largely outside the memory limit guarded by PHP.
This function does not accept all pathnames, in spite of its documentation.
$ php -r 'print_r( simplexml_load_file("%25.xml"));'
PHP Warning: simplexml_load_file(): I/O warning : failed to load external entity "%25.xml" in Command line code on line 1
I stumbled on this: a single element with a simple string in it becomes a string, but a single element with a *space* in it becomes an Array, with one element, the string space.
I'm sure to XML mystics this is wise and wonderful but it really confused me, and I thought it might confuse others.
<?php
$parsed = simplexml_load_string('<container><space> </space><blank></blank><string>hello</string></container>');
$content = json_decode(json_encode($parsed),TRUE);
var_dump($content);
/* Output is:
array(3) {
'space' => array(1) { ← did NOT expect this!
[0] => string(1) " "
}
'blank' => array(0) { }
'string' => string(5) "hello"
}
*/
If you don't want that the CDATA values get escaped, just load the XML with LIBXML_NOCDATA as an 3rd argument.
Note: A PHP version >= 5.1.0 is required for this to work.
Example:
<?php simplexml_load_file('xmldatei.xml', null, LIBXML_NOCDATA); ?>
Suppose you have loaded a XML file into $simpleXML_obj.
The structure is like below :
SimpleXMLElement Object
(
[node1] => SimpleXMLElement Object
(
[subnode1] => value1
[subnode2] => value2
[subnode3] => value3
)
[node2] => SimpleXMLElement Object
(
[subnode4] => value4
[subnode5] => value5
[subnode6] => value6
)
)
When searching a specific node in the object, you may use this function :
<?php
function &getXMLnode($object, $param) {
foreach($object as $key => $value) {
if(isset($object->$key->$param)) {
return $object->$key->$param;
}
if(is_object($object->$key)&&!empty($object->$key)) {
$new_obj = $object->$key;
$ret = getCfgParam($new_obj, $param);
}
}
if($ret) return (string) $ret;
return false;
}
?>
So if you want to get subnode4 value you may use this function like this :
<?php
$result = getXMLnode($simpleXML_obj, 'subnode4');
echo $result;
?>
It display "value4"
Be careful if you are using simplexml data directly to feed your MySQL database using MYSQLi and bind parameters.
The data coming from simplexml are Objects and the bind parameters functions of MySQLi do NOT like that! (it causes some memory leak and can crash Apache/PHP)
In order to do this properly you MUST cast your values to the right type (string, integer...) before passing them to the binding methods of MySQLi.
I did not find that in the documentation and it caused me a lot of headache.
Occasionally you may try to load a file and have it complain about an entity and throw a parser error.
If this is the case, check to make sure that the file in question does not contain an ampersand (&) without a corresponding entity reference.
If it does, or if you want to err on the side of caution, then instead of using simplexml_load_file, try this:
$file = file_get_contents('stuff.xml');
$temp = preg_replace('/&(?!(quot|amp|pos|lt|gt);)/', '&', $file);
$xml = simplexml_load_string($temp) or die("xml not loading");
Read the file into a string, add 'amp;' after any '&' that is not part of a character entity, then parse the string as xml.
If you have some nodes which are having special characters, it would not load properly
for an instance see the nodes below
<node:number>1538-7445</node:number>
<node:coverDisplayDate>Sep 1 2012 12:00:00:000AM</node:coverDisplayDate>
either you have to change the : to other special characters like '-' in order to convert it properly
Correct Node
<node-number>1538-7445</node-number>
<node-coverDisplayDate>Sep 1 2012 12:00:00:000AM</node-coverDisplayDate>
I have wasted my precious time while debugging this. Please aware about this. ?
If you are loading many files, this may slow down your page load time.
To set a timeout, use file_get_context and then simplexml_load_string
<?php
$fp = fopen('http://www.example.com/rss', false, stream_create_context(array('http' => array('timeout', '1.5'))));
if ($fp) {
print_r( simplexml_load_string($fp) );
} else {
echo "The request timed out";
}
?>