PHP 日本研討會 2024

SimpleXML 函數

目錄

新增筆記

使用者貢獻的筆記 37 筆筆記

18
help :-) @ theapotek :-) com
13 年前
如果您在存取 simplexml 文件中的 CDATA 時遇到問題,則不需要在使用 simplexml 載入之前使用 str_replace/preg_replace 將 CDATA 取出。

您可以改為執行此操作,所有 CDATA 內容將以字串形式合併到元素內容中。

$xml = simplexml_load_file($xmlfile,
'SimpleXMLElement', LIBXML_NOCDATA);
8
cmsa at gmx dot de
17 年前
我遇到了實體的問題。

我的第一個解決方案
我以這種方式儲存資料
$ENTRY_->
addchild('Nachricht',htmlentities($_POST["blog"]));

XML 檔案中的實體如下所示
<!ENTITY auml "&amp;auml">

我以這種方式載入資料
html_entity_decode($ENTRY->Nachname);

但在儲存和
載入 xml 檔案後,實體項目
<!ENTITY auml "&amp;auml">
消失了。很奇怪...

我的第二個解決方案
以這種方式儲存資料
$ENTRY_->
addchild('Nachricht',htmlentities(htmlentities($_POST["blog"])));

我現在可以使用 html_entity_decode 載入它,而不需要
XML 檔案中的實體項目!
我使用 äöü 進行測試。

希望這有幫助。
5
joel [來自網站] purerave.com
17 年前
雖然它在任何地方都沒有提到,但是從無效字串建立新的 SimpleXMLElement 物件會擲回例外。它在 php 日誌中看起來很醜,因為它會在多行中傾印堆疊。

建立新 SimpleXMLElement 物件的正確方法如下
<?php
$xmlstr
= ''; // 空字串會擲回例外
try {
$xml = new SimpleXMLElement($xmlstr);
} catch (
Exception $e) {
// 處理錯誤
echo '$xmlstr 不是有效的 xml 字串';
}
?>
4
brcavanagh AT NO SPAM hotmail.com
19 年前
如果您希望將 SimpleXML 用於讀取 XML 文件以外的任何用途,您應該重新考慮,並使用 XML DOM 程式庫。當您在 DOM 中實作足夠的公用程式來處理 SimpleXML 中的所有挫折時,您會發現使用 SimpleXML 的目的已蕩然無存。這有一些原因,而且已經有很多變通方法,但主要問題如下

1) 沒有複雜的節點指派。您無法切換節點或替換節點。

2) 無法附加新的子節點

3) 無論何時執行類似 $new_node = $xml_doc->node 的操作,即使使用 clone 方法,您也始終會取得參考,這會使腳本當機。

除此之外,它是讀取文件的絕佳工具。
5
r dot m dot 0100101 at gmail dot com
11 年前
這是對 https://php.dev.org.tw/manual/en/ref.simplexml.php#103617 的函數的稍作調整。
他們提供的函數會將 simpleXML 轉換為陣列,但僅限於最高層級。一旦您使用 is_object 新增 is_array 檢查,它應該會將每個層級轉換為陣列(對我來說,它確實經過了 3 個層級)。

function simpleXmlObjectToArray ( $xmlObject, $out = array () )
{
foreach ( (array) $xmlObject as $index => $node )
$out[$index] = ( is_object ( $node ) || is_array($node) )
? simpleXmlObjectToArray ( $node )
: $node;

return $out;
}
祝您編碼愉快!
6
William Fahria
11 年前
簡單的實作
您可以將文字格式的直接 XML 通知給函數。

function eoXML2Array($xmlContent, $out = array()){
$xmlObject = is_object($xmlContent) ? $xmlContent : simplexml_load_string($xmlContent);
foreach((array) $xmlObject as $index => $node)
$out[$index] = ( is_object($node) || is_array($node) ) ? eoXML2Array( $node ) : $node;
return $out;
}

用法:$your_array = eoXML2Array(your xml text);
5
paul at preinheimer dot com
19 年前
您好,

如果您想要存取名稱中包含破折號的元素(這在國會圖書館以及 NWS 提供的 XML 文件中很常見),則需要以稍微不同的方式處理它。

您可以使用 XPATH,它運作良好,但每次都會傳回結果陣列,即使只有一個結果也是如此。
例如。

<?php
$xml
->xpath('/data/time-layout/start-valid-time');
?>

您也可以選擇僅封裝包含破折號的元素名稱
<?php $xml->data->{'time-layout'}->{'start-valid-time'} ?>

--

在一個只有部分相關的附註中,處理 SimpleXML 是我唯一一次使用 PHP 進行強制轉換的時候。雖然在有效時間中反覆執行 (foreach) 時,echo'ing 元素運作良好(它只是 echo 輸出適當的時間),但將它指派給另一個變數會導致 SimpleXML 物件包含要指派的時間,而不僅僅是時間本身。這可以透過將時間強制轉換為字串來解決

<?php
foreach($xml->data->{'time-layout'}->{'start-valid-time'} AS $time)
{
$weatherDates[] = (string) $time;
}
?>
4
brandonkirsch at gmail dot com
11 年前
與此處發佈的其他筆記相反,SimpleXML *無法*正確處理非 UTF8 編碼的 XML 文件。

當使用擴展字元(即位元組值大於 127)時,使用 PHP 5.2.17 或 5.5.1 時,正確宣告且編碼為 "iso-8859-1" 的 XML 文件將無法使用 SimpleXML 進行解析

另一方面,DOMDocument 會正確解析傳入的 iso-8859-1 XML 文件,並且也可以用於執行字元翻譯為 UTF8

$dom = new DOMDocument();

if($dom->loadXML($fileContents)){ // $fileContents 是一個在宣告中指定 iso-8859-1 編碼的 XML 文件
$dom->encoding = 'utf-8'; // 將文件編碼轉換為 UTF8
return $dom->saveXML(); // 返回有效的 utf8 編碼 XML
6
andrvm
16 年前
<?php
/**
* 使用 xpath 移除 XML 節點/多個節點
*
* @param SimpleXMLElement $xml
* @param string XPath $path
* @param string ('one'|'child'|'all') $multi
*
* 用法:
*
* 範例 xml 檔案 - http://ru2.php.net/manual/ru/ref.simplexml.php
*
* $xml = simplexml_load_file($xmlfile);
*
* //1. 僅移除 1 個節點 (不含子節點)
* // $path 必須只回傳 1 個 (唯一) 不含子節點的節點
* removeNode($xml, '//movie/rating[@type="thumbs"]');
*
* //2. 移除 1 個節點 (含 1 個子節點)
* // $path 可以回傳任何節點 - 只會移除第一個節點
* // 以及所有子節點
* removeNode($xml, '//characters', 'child')
*
* //3. 移除所有節點 (含子節點)
* // $path 可以回傳任何節點 - 會移除所有
* // 以及所有子節點
* removeNode($xml, '//rating', 'all')
*
* $xml->asXML($xmlfile);
*
*/
function removeNode($xml, $path, $multi='one')
{
$result = $xml->xpath($path);

# 針對錯誤的 $path
if (!isset($result[0])) return false;

switch (
$multi) {
case
'all':
$errlevel = error_reporting(E_ALL & ~E_WARNING);
foreach (
$result as $r) unset ($r[0]);
error_reporting($errlevel);
return
true;

case
'child':
unset(
$result[0][0]);
return
true;

case
'one':
if (
count($result[0]->children())==0 && count($result)==1) {
unset(
$result[0][0]);
return
true;
}

default:
return
false;
}
}
?>

p.s. 使用後 (如果刪除了所有節點)
<?php

function trimXml($xmlfile)
{
$dom = new DOMDocument();

$dom->preserveWhiteSpace = false;

if (!
$dom->load($xmlfile)) return false;

$dom->formatOutput = true;

if (!
$dom->save($xmlfile)) return false;

return
true;
}
?>
4
T CHASSAGNETTE t_chassagnette at yahoo dot fr
19 年前
另一個使用 SIMPLEXML 將 XML 文件解析成 PHP 陣列的方法,靈感來自 Daniel FAIVRE !

<?php
function xml2php($xml)
{
$fils = 0;
$tab = false;
$array = array();
foreach(
$xml->children() as $key => $value)
{
$child = xml2php($value);

//處理屬性
foreach($node->attributes() as $ak=>$av)
{
$child[$ak] = (string)$av;

}

//檢查新的子元素是否已存在於陣列中
if($tab==false && in_array($key,array_keys($array)))
{
//如果這個元素已經在陣列中,我們將建立索引陣列
$tmp = $array[$key];
$array[$key] = NULL;
$array[$key][] = $tmp;
$array[$key][] = $child;
$tab = true;
}
elseif(
$tab == true)
{
//在現有的陣列中加入元素
$array[$key][] = $child;
}
else
{
//加入簡單的元素
$array[$key] = $child;
}

$fils++;
}


if(
$fils==0)
{
return (string)
$xml;
}

return
$array;

}
?>
4
ngkongs at gmail dot com
16 年前
修正我之前發布的函數,有個錯誤的引號位置

function implode2($glue="", $var){
if ($var){
foreach ($var as $value){
$array[]=strval($value);
}
return implode($glue, $array);
}
else return false;
}
5
Eric
11 年前
如果 SimpleXMLObject 包含一個陣列,加入 is_array() 可以讓函數持續尋找物件。

<?php
function xml2array ( $xmlObject, $out = array () )
{
foreach ( (array)
$xmlObject as $index => $node )
$out[$index] = ( is_object ( $node ) || is_array ( $node ) ) ? xml2array ( $node ) : $node;

return
$out;
}
?>
3
Douglas Marsh
15 年前
SimpleXML 非常適合將 XML 資料載入/轉換為原生 PHP 資料結構。我當時考慮粗略地搜尋 SVG 的寬度/高度,既然它實際上是一個 XML 檔案... 我找到一個超簡單的方法來解析出我想要的資訊

<?php
// 為了方便閱讀,將不完整的 SVG 資料內嵌
$RawXML = <<< XML
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://www.example.com/dc"
xmlns:cc="http://www.example.com/cc"
xmlns:rdf="http://www.example.com/rdf"
xmlns:svg="http://www.example.com/svg"
xmlns="http://www.example.com/"
xmlns:sodipodi="http://www.example.com/sodipodi"
xmlns:inkscape="http://www.example.com/inkscape"
id="svg2"
sodipodi:version="0.32"
inkscape:version="0.46"
width="586.25"
height="743.75"
xml:space="preserve"
sodipodi:docname="some_svg_file.svg"
inkscape:output_extension="org.inkscape.output.svg.inkscape">
<!-- 為了簡短,移除了一些部分 -->
</svg>
XML;

$svg = new SimpleXMLElement($RawXML);

$height = $svg['height'];
$width = $svg['width'];

echo
"寬度 x 高度為: ${width} x ${height} \n";

?>
4
daniel dot oconnor at gmail dot com
18 年前
SimpleXML 處理命名空間,但這裡的文檔並未詳細說明。

如果你想解析例如 Open Office 清單檔案或一段 RDF/XML,你必須透過命名空間網址來取得元素和屬性。

範例
<?php
function display($in) {
if (
file_exists($in)) {
$xml = simplexml_load_file($in);
} else {
throw new
Exception($in . " does not exist");
}

$manifest = $xml->children('http://openoffice.org/2001/manifest');

foreach (
$manifest->xpath('//manifest:file-entry') as $file) {
foreach (
$file->attributes('http://openoffice.org/2001/manifest') as $key => $value) {
print
"Key:" . $key . "\n";
print
"Value:" . $value . "\n";
}
}

}
?>

檔案:manifest.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE manifest:manifest PUBLIC "-//OpenOffice.org//DTD Manifest 1.0//EN" "Manifest.dtd">
<manifest:manifest xmlns:manifest="http://openoffice.org/2001/manifest">
<manifest:file-entry manifest:media-type="application/vnd.sun.xml.writer" manifest:full-path="/"/>
<manifest:file-entry manifest:media-type="application/vnd.sun.xml.ui.configuration" manifest:full-path="Configurations2/"/>
<manifest:file-entry manifest:media-type="application/binary" manifest:full-path="layout-cache"/>
<manifest:file-entry manifest:media-type="text/xml" manifest:full-path="content.xml"/>
<manifest:file-entry manifest:media-type="text/xml" manifest:full-path="styles.xml"/>
<manifest:file-entry manifest:media-type="text/xml" manifest:full-path="meta.xml"/>
<manifest:file-entry manifest:media-type="" manifest:full-path="Thumbnails/thumbnail.png"/>
<manifest:file-entry manifest:media-type="" manifest:full-path="Thumbnails/"/>
<manifest:file-entry manifest:media-type="text/xml" manifest:full-path="settings.xml"/>
</manifest:manifest>
5
onPHP5.com
17 年前
文件中沒有說明,但如果來源 XML 宣告有其他的編碼,SimpleXML 會將所有文字轉換為 UTF-8。例如,如果來源有以下 XML 宣告

<?xml version="1.0" encoding="windows-1251" ?>

產生的 SimpleXMLElement 中的所有文字都會自動以 UTF-8 編碼。
3
Arnaud Bienvenu
18 年前
在 PHP 5.1.4 版本中,嘗試迭代不存在的節點實際上會建立該節點。

<?
$xml = simplexml_load_string('<root></root>');
foreach($xml->b as $dummy);
echo $xml->asXML();
?>

會輸出

<?xml version="1.0"?>
<root><b/></root>

您可能會認為這是一個錯誤,但 PHP 開發人員似乎將其視為一個功能:http://bugs.php.net/bug.php?id=39164
2
julien dot breiner at laposte dot net
12 年前
僅使用 SimpleXML 合併兩個 XML

<?php
private function mergeXML(&$base, $add)
{
$new = $base->addChild($add->getName());
foreach (
$add->attributes() as $a => $b) {
$new[$a] = $b;
}
foreach (
$add->children() as $child) {
$this->mergeXML($new, $child);
}
}
?>

用法:<?php mergeXML($xmlElement, simplexml_load_string($toMerge)) ?>
2
nelson_menezes at yahoo dot co dot uk
19 年前
請注意,SimpleXML 預期以 UTF-8 編碼讀取和輸出 XML。如果您的輸入 XML 檔案不是以 UTF-8 儲存,您需要在檔案頂部加入類似這樣的行(根據使用的編碼進行調整)

<?xml version="1.0" encoding="ISO-8859-1" ?>

在輸出方面,如果您不提供/處理 UTF-8,您需要使用 utf8_decode() [編者註:但這僅適用於 ISO-8859-1,不適用於其他編碼]。常見錯誤:http://bugs.php.net/bug.php?id=28154
3
k dot antczak at livedata dot pl
13 年前
將 XML 物件轉換為陣列的快速程式碼片段

<?php
function xml2array ( $xmlObject, $out = array () )
{
foreach ( (array)
$xmlObject as $index => $node )
$out[$index] = ( is_object ( $node ) ) ? xml2array ( $node ) : $node;

return
$out;
}
?>

玩得開心! ;-)
1
james dot ellis at gmail dot com
16 年前
雖然 SimpleXML 是一個強大的工具,但使用它來處理和處理大型 XML 文件和字串的開發人員應該仔細考慮其記憶體使用需求。
SimpleXML 需要在對樹狀結構執行任何處理動作之前,整個 XML 樹狀結構都可用 - 這需要整個樹狀結構都載入到記憶體中。對於 40kb 的 XML 檔案來說沒問題,但在處理 > 100MB 的檔案時,您會看到效能下降,尤其是在伺服器繁忙時。

處理大型 XML 檔案的替代方法是 XMLReader 類別,它以串流模式運作,這裡提供了一個很好的教學
http://www.ibm.com/developerworks/library/x-pullparsingphp.html

XML 是一種非常冗長的格式。如果您正在處理大型資料結構,尤其是在 Web 服務中,您真的需要將資料表示為 XML 樹狀結構嗎? - 其他序列化格式(例如 JSON、序列化的 PHP、Google Protocol Buffers(http://code.google.com/p/protobuf/))甚至 CSV 都可以顯著減少處理時間、頻寬和處理大型檔案時的負載。一個 110MB 的 XML 檔案可以變成一個 65MB 的 CSV 檔案,其中包含相同的資料,僅僅因為資料識別符號(標籤)在整個文件中只表示一次。
1
m0sh3 at hotmail dot com
16 年前
請注意類似這樣的怪異之處

<?php

$a
= new SimpleXMLElement('<a><b/></a>');

$a->b = 'test &amp; test';
$a->c = 'test &amp; test';

print_r($a);
/*
輸出:

SimpleXMLElement 物件
(
[b] => test & test
[c] => test &amp; test
)
*/
1
codje2 at lboro dot ac dot uk
17 年前
有時將資料儲存類型混合使用會很好。這是一個非常簡單的 SQL 轉換為 XML 的轉換器。將 SQL 查詢饋入,它會以 XML 格式輸出結果。

第一個參數應該是 mysql_query 結果
(可選)第二個是每行的 XML 名稱(即 XML 的第二層)
(可選)第三個是 XML 文件名稱,根名稱

<?php
$result
=mysql_query("SELECT * FROM users");
sql_to_xml($result,"users","members");

function
sql_to_xml($mysql_result,$row_name="row",$doc_name="root")
{

$xml= new SimpleXMLElement("<$doc_name></$doc_name>");
while(
$line=mysql_fetch_assoc($mysql_result))
{
$row=$xml->addChild($row_name);
foreach(
$line as $column => $value)
{
$row->$column="$value";
}
}
return
$xml->asXML();
}

?>
1
karsten dot bruch at bms-verlage dot de
17 年前
建立新的 XML 文件並加入帶有母音變音等的文字時

<?php $SimpleXMLElement->asXML(); ?>

將會靜默地不輸出任何帶有母音變音符號的內容。

在加入母音變音符號及類似符號時,請使用 htmlentities () 來解決此「問題」
2
lordi at msdi dot ca
17 年前
如果您需要在從 simplexml 文件中提取的值上執行數學計算,您可能需要將該值轉換為浮點數,以防止精度損失。這是一個範例

<?php
$objXML
= new SimpleXMLElement('<test x="-123.45"></test>');

//正確顯示
echo $objXML['x']."\n";

//小數點遺失
echo $objXML['x'] + $objXML['x']."\n";

$x = $objXML['x'];

//如果我們轉換類型為 float 則可正常運作
echo (float)$objXML['x'] + (float)$objXML['x']."\n";

//以字串計算,沒問題
echo "-123.45" + "-123.45";

?>

這是因為 $objXML['x'] 不是字串 (PHP 會自動轉換) 也不是浮點數,而是一個 SimpleXMLElement 物件。

"echo var_dump($x);" 將會輸出以下內容
~~
object(SimpleXMLElement)#3 (1) {
[0]=>
string(7) "-123.45"
}
~~

我已在 PHP 上提交錯誤回報,但這是他們給我的回覆

~~
狀態:不會修正

此行為由引擎定義,而非擴展。當對物件執行數學運算時,它們會被視為整數。使用者有責任將物件轉換為適當的類型以維持正確的精度。
~~
2
anthony dot parsons at manx dot net
17 年前
如果您正在處理大量的 HTML 或混合內容的 XML,您可能會想使用 DOM 函數而不是 SimpleXML。例如以下情況:
<?php
$html
= new SimpleXMLElement('<div><p>Some text, <a href="#">a link,</a> more text</p></div>');

echo
$html->p->a,"<br>\n"; // "a link,"
echo $html->p; // "Some text, more text" (!)
?>
在上面的例子中,由於 SimpleXML 表示資料的方式,重新建構原始的標記是不可能的。
2
php at NOSPAM dot coutch dot com
17 年前
當像範例 (#Example 2134. 設定值) 中設定屬性時會發生記憶體洩漏

這在網頁腳本中可能不會被注意到(除非您進行大量的 XML 操作),但我在處理大量 XML 檔案的獨立腳本中遇到了這個問題。

以下程式碼會很快地耗盡記憶體

<?php
include 'example.php';

while (
true) {
$xml = new SimpleXMLElement($xmlstr);
$xml->movie[0]->characters->character[0]->name = 'Miss Coder';
}
?>

然而,以下程式碼看起來行為正常

<?php
include 'example.php';

while (
true) {
$xml = new SimpleXMLElement($xmlstr);
$c = $xml->xpath("//character");
$c[0]->name = 'Miss Coder';
}
?>

這看起來像是錯誤 #38604,而且我剛確認在 6.0.0-dev(至少在 Windows 上)已經修正。它在 5.2.1 或 5.2.2-dev (2/21 版本) 中尚未修正,所以對於 5.2 的使用者,請使用第二種形式來避免洩漏。
2
matt at mattbostock dot com
18 年前
當使用 var_export 來除錯元素屬性時要小心 - 它不會工作!請務必使用 print() 或類似的方式來檢查元素屬性的內容。
0
Pyetro Costa [pyetrosafe at gmail dot com]
5 年前
在查看了 "https://php.dev.org.tw/manual/en/ref.simplexml.php#103617" 的 xml2array 函式以及 "https://php.dev.org.tw/manual/en/ref.simplexml.php # 112038 ",並且仍然對將空標籤轉換為 null 做了更改...我覺得有必要將結果作為物件來處理,並保持陣列的陣列形式。得出這個函數:
<?php

private function xml2Object($xmlObject, $out = null) {
$out = (is_object($xmlObject) ? new \stdClass : array());
foreach ((array)
$xmlObject as $index => $node )
if (
is_array($out)) {
$out[$index] = (is_object($node) || is_array($node)) ? (($node instanceof \SimpleXMLElement) && count((array) $node)==0 ? null : $this->xml2Object($node)) : $node;
} else
$out->{$index} = (is_object($node) || is_array($node)) ? (($node instanceof \SimpleXMLElement) && count((array) $node)==0 ? null : $this->xml2Object($node)) : $node;
return
$out;
}
?>

該函式的結果如下所示
<?php
$xml
= simplexml_load_string('<?xml version="1.0" encoding="UTF-8" standalone="no"?><results><l1_elm1><l2_elm1>Some Text</l2_elm1><l2_elm2/></l1_elm1><l1_elm2><l2_elm1><l3_elm1>Array Index[0] - First property</l3_elm1><l3_elm2>Array Index[0] - Second property</l3_elm2><l3_elm3>Array Index[0] - Third property</l3_elm3></l2_elm1><l2_elm1><l3_elm1>Array Index[1] - First property</l3_elm1><l3_elm2>Array Index[1] - Second property</l3_elm2><l3_elm3>Array Index[1] - Third property</l3_elm3></l2_elm1></l1_elm2><l1_elm3/></results>');

var_dump( $this->xml2Object($xml) );

// var_dump xml2Object 執行結果
object(stdClass)#339 (3) {
["l1_elm1"]=>object(stdClass)#344 (2) {
["l2_elm1"]=>string(9) "Some Text"
["l2_elm2"]=>NULL
}
[
"l1_elm2"]=>object(stdClass)#347 (1) {
["l2_elm1"]=>array(2) {
[
0]=>object(stdClass)#348 (3) {
["l3_elm1"]=>string(31) "Array Index[0] - First property"
["l3_elm2"]=>string(32) "Array Index[0] - Second property"
["l3_elm3"]=>string(31) "Array Index[0] - Third property"
}
[
1]=>object(stdClass)#349 (3) {
["l3_elm1"]=>string(31) "Array Index[1] - First property"
["l3_elm2"]=>string(32) "Array Index[1] - Second property"
["l3_elm3"]=>string(31) "Array Index[1] - Third property"
}
}
}
[
"l1_elm3"]=>NULL
}

// VarDump Symphony xml2Object 執行結果類似於
object (#345) {
+"l1_elm1": object (#339) {
+"l2_elm1": "Some Text"
+"l2_elm2": null
}
+
"l1_elm2": object (#347) {
+"l2_elm1": array(2) {
[
0] => object (#348) {
+"l3_elm1": "Array Index[0] - First property"
+"l3_elm2": "Array Index[0] - Second property"
+"l3_elm3": "Array Index[0] - Third property"
}
[
1] => object (#349) {
+"l3_elm1": "Array Index[1] - First property"
+"l3_elm2": "Array Index[1] - Second property"
+"l3_elm3": "Array Index[1] - Third property"
}
]
}
+
"l1_elm3": null
}
?>
0
thomas at guenneguez dot com
12 年前
僅使用 SimpleXML 合併兩個 XML
如果節點僅包含值,則修正函式。

<?php
function mergeXML(&$base, $add)
{
if (
$add->count() != 0 )
$new = $base->addChild($add->getName());
else
$new = $base->addChild($add->getName(), $add);
foreach (
$add->attributes() as $a => $b)
{
$new->addAttribute($a, $b);
}
if (
$add->count() != 0 )
{
foreach (
$add->children() as $child)
{
mergeXML($new, $child);
}
}
}
?>

用法:<?php mergeXML($xmlElement, simplexml_load_string($toMerge)) ?>
0
philippe_marc_--a---t--_novartis_com
16 年前
提示:如果您在使用 simpleXML 時遇到記憶體問題。
您可能需要使用 PHP>5.2.5 以避免該問題:http://bugs.php.net/bug.php?id=38604
如果無法如此,請避免像「foreach ( $xmldata->node as $node )」這樣的呼叫。
0
php at werner dash ott dot de
17 年前
關於 SimpleXML 和 sessions

當在 session 的上下文中建立 SimpleXML 物件 (更精確地說:SimpleXMLElement 物件) 並將其儲存在 $_SESSION['XMLobject'] 中時,此物件無法「存活」過 session!

當重新進入 session 時,print_r($_SESSION['XMLobject']) 會顯示

['XMLobject'] => SimpleXMLElement Object
Warning: Node no longer exists in /your_php_file.php on line xyz
(
)

(為了更好的可讀性,已簡化訊息。)
0
Jason Sheets <jsheets at shadonet dot com>
18 年前
這是我的 Simple XML 轉陣列函式,它是遞迴的,並且具有保持鍵值關係的優點,並且對我來說運作良好。

<?php
function XMLToArray($xml)
{
if (
$xml instanceof SimpleXMLElement) {
$children = $xml->children();
$return = null;
}

foreach (
$children as $element => $value) {
if (
$value instanceof SimpleXMLElement) {
$values = (array)$value->children();

if (
count($values) > 0) {
$return[$element] = XMLToArray($value);
} else {
if (!isset(
$return[$element])) {
$return[$element] = (string)$value;
} else {
if (!
is_array($return[$element])) {
$return[$element] = array($return[$element], (string)$value);
} else {
$return[$element][] = (string)$value;
}
}
}
}
}

if (
is_array($return)) {
return
$return;
} else {
return
$false;
}
}
?>
-2
Pyetro Costa [pyetrosafe at gmail dot com]
5 年前
這只是對 https://php.dev.org.tw/manual/en/ref.simplexml.php#112038 的函式所做的新調整。

透過 is_array 增加檢查已將轉換層級提高至少 3 層,然而,空的標籤會被轉換為 SimpleXMLElement 類別物件,增加類型和大小檢查,將這些空的標籤轉換為 null。

請看範例
<?php
// https://php.dev.org.tw/manual/en/ref.simplexml.php#112038 的函式
function xml2array($xmlObject, $out = array ()) {
foreach ((array)
$xmlObject as $index => $node )
$out[$index] = (is_object($node) || is_array($node)) ? xml2array($node) : $node;
return
$out;
}

$xml = simplexml_load_string('<?xml version="1.0" encoding="UTF-8" standalone="no"?><results><level1><l1_elm1><level2><l2_elm1>Some Text</l2_elm1><l2_elm2/></level2></l1_elm1><l1_elm2>Other String</l1_elm2><l1_elm3/></level1></results>');
$XML2Array = xml2array($xml);
var_dump($xml);
var_dump($XML2Array);

// 結果如下
// simplexml_load_string 的結果
object(SimpleXMLElement)#227 (1) {
["level1"]=>object(SimpleXMLElement)#226 (3) {
["l1_elm1"]=>object(SimpleXMLElement)#236 (1) {
["level2"]=>object(SimpleXMLElement)#238 (2) {
["l2_elm1"]=>string(9) "Some Text"
["l2_elm2"]=>object(SimpleXMLElement)#239 (0) {}
}
}
[
"l1_elm2"]=>string(12) "Other String"
["l1_elm3"]=>object(SimpleXMLElement)#237 (0) {}
}
}

// xml2array 函式的結果
array(1) {
[
"level1"]=>array(3) {
[
"l1_elm1"]=>array(1) {
[
"level2"]=>array(2) {
[
"l2_elm1"]=>string(9) "Some Text"
["l2_elm2"]=>array(0) {}
}
}
[
"l1_elm2"]=>string(12) "Other String"
["l1_elm3"]=>array(0) {}
}
}
?>

現在,檢查節點類型和大小,如果節點是 SimpleXMLElement 的實例且 count == 0,則將值設定為 null(或您偏好的空字串 "");
<?php
function xml2array($xmlObject, $out = array ()) {
foreach ((array)
$xmlObject as $index => $node )
$out[$index] = (is_object($node) || is_array($node)) ? (($node instanceof \SimpleXMLElement) && count((array) $node)==0 ? null : xml2array($node)) : $node;
return
$out;
}

$xml = simplexml_load_string('<?xml version="1.0" encoding="UTF-8" standalone="no"?><results><level1><l1_elm1><level2><l2_elm1>Some Text</l2_elm1><l2_elm2/></level2></l1_elm1><l1_elm2>Other String</l1_elm2><l1_elm3/></level1></results>');
var_dump(xml2array($xml));

// 現在結果如下
array(1) {
[
"level1"]=>array(3) {
[
"l1_elm1"]=>array(1) {
[
"level2"]=>array(2) {
[
"l2_elm1"]=>string(9) "Some Text"
["l2_elm2"]=>NULL
}
}
[
"l1_elm2"]=>string(12) "Other String"
["l1_elm3"]=>NULL
}
}
?>
-1
nathan at gimpstraw dot com
16 年前
我正在使用 SimpleXML 處理從 API 請求回傳的資料,我遇到了 CDATA 問題和從 html 實體得到的錯誤,這是我想出的解決方案,不知道是不是最實用的,但它確實有效。

<?php
$str
= <<< XML
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<menu>
<item>
<title><![CDATA[Caf&eacute;]]></title>
<description><![CDATA[Some description.]]></description>
</item>
</menu>
XML;

$str = preg_replace("/\<\!\[CDATA\[(.*?)\]\]\>/ies", "'[CDATA]'.base64_encode('$1').'[/CDATA]'", $str);
$xml = new SimpleXMLElement($str);

// 返回項目的標題
foreach ($xml->item as $item) {
$tmp = (string) $item->title;
$tmp = preg_replace("/\[CDATA\](.*?)\[\/CDATA\]/ies", "base64_decode('$1')", $tmp);
echo
$tmp;
}
?>
-1
Andrez zenarter at hotmail dot com
15 年前
我只想為
「將一個 simplexml 附加/合併/結合到另一個」
新增一個附加功能,父節點也應具有屬性。

<?php

function append_simplexml(&$simplexml_to, &$simplexml_from)
{

static
$firstLoop=true;

//這裡添加屬性到父節點
if( $firstLoop )
{
foreach(
$simplexml_from->attributes() as $attr_key => $attr_value )
{
$simplexml_to->addAttribute($attr_key, $attr_value);
}
}

foreach (
$simplexml_from->children() as $simplexml_child)
{
$simplexml_temp = $simplexml_to->addChild($simplexml_child->getName(), (string) $simplexml_child);
foreach (
$simplexml_child->attributes() as $attr_key => $attr_value)
{
$simplexml_temp->addAttribute($attr_key, $attr_value);
}

$firstLoop=false;

append_simplexml($simplexml_temp, $simplexml_child);
}

unset(
$firstLoop=false );
}

?>

我遇到一個問題,就是將一個物件賦值給一個稍後會被當成物件使用的變數,然後我找到了上面的程式碼,它解決了我一半的問題。我覺得它應該也要把父節點的名稱也賦值進去,但它沒有。有更好的程式碼嗎?
-1
codejunky32 at NOSPAM dot com
15 年前
我只是想發一篇文,說明如何從 SimpleXMLElement 中提取值。它不像你想像的那麼簡單。因為它是一個複雜的物件,你不能直接存取元素。以下是一個範例資料,它代表一個 SimpleXmlElement 的 var_dump。

array(1) {
[0]=>
object(SimpleXMLElement)#13 (2) {
["@attributes"]=>
array(1) {
["name"]=>
string(5) "title"
}
[0]=>
string(19) "PHP Tech Book"
}
}

如果你想提取書的標題,你必須像這樣將指定的元素轉換為字串。
$newTitle = (string) $title[0];

$title 變數是您使用 simplexml_load_string 等從 xml 文件中提取的 SimpleXMLElement。要從 xml 文件中最初存取標題元素,可以使用 xpath 這樣做。
$title = $doc->xpath('str[@name="title"]');

希望這對大家有所幫助。
-3
info at ajaxforum dot ru
15 年前
將一個 simplexml 附加/合併/結合到另一個

<?php
include 'example.php';
$el1 = new SimpleXMLElement($xmlstr);
$el2 = new SimpleXMLElement($xmlstr);

// 錯誤的方式!
// php 會將 $el2->movie[0] 靜默地轉換為字串
$el1->addChild('movie', $el2->movie[0]);

// 錯誤的方式!
// php 5.1 會將 $el2->movie[0] 轉換為字串並產生警告:It is not yet possible to assign complex types to properties. It is not possible to assign complex types to nodes
// php 5.2 會將 $el2->movie[0] 靜默地轉換為字串
$el1->addChild('movie');
$el1->movie[2] = $el2->movie[0];

// 正確的方式!
$el1_movie = $el1->addChild('movie');
append_simplexml($el1_movie, $el2->movie[0]);

echo
"<pre>"; print_r($el1); echo "</pre>";

/**
* 將一個 simplexml 加入到另一個
*
* @param object $simplexml_to
* @param object $simplexml_from
* @author Boris Korobkov
* @link http://www.ajaxforum.ru/
*/
function append_simplexml(&$simplexml_to, &$simplexml_from)
{
foreach (
$simplexml_from->children() as $simplexml_child)
{
$simplexml_temp = $simplexml_to->addChild($simplexml_child->getName(), (string) $simplexml_child);
foreach (
$simplexml_child->attributes() as $attr_key => $attr_value)
{
$simplexml_temp->addAttribute($attr_key, $attr_value);
}

append_simplexml($simplexml_temp, $simplexml_child);
}
}
?>
To Top