PHP: استخدام SimpleXML للحلق من خلال جميع مستويات ملف XML
سؤال
لدي وظيفة تستخدم SimpleXML لإرجاع المستوى الأول من العقد في ملف XML واكتبها في قائمة غير مرتبة:
function printAssetMap() {
$xml = simplexml_load_file(X_ASSETS);
$assets = $xml->asset;
$html = '<ul>'."\n";
foreach ($assets as $asset) {
$html .= '<li id="asset'.$asset->asset_assetid.'"><ins> </ins><a href="#">'.$asset->asset_name.' ['.$asset->asset_assetid.']</a></li>'."\n";
}//end foreach
$html .= '</ul>'."\n";
return $html;
}// printAssetMap()
XML أنا أستخدمها ، والتي لديها العقد المتداخلة:
<?xml version="1.0"?>
<assets>
<asset>
<asset_name>Home</asset_name>
<asset_url>/home</asset_url>
<asset_assetid>1</asset_assetid>
</asset>
<asset>
<asset_name>Projects</asset_name>
<asset_url>/projects</asset_url>
<asset_assetid>2</asset_assetid>
<asset>
<asset_name>Portfolio</asset_name>
<asset_url>/projects/portfolio</asset_url>
<asset_assetid>3</asset_assetid>
</asset>
<asset>
<asset_name>Current Jobs</asset_name>
<asset_url>/projects/current-jobs</asset_url>
<asset_assetid>4</asset_assetid>
</asset>
</asset>
</assets>
الآن ، بدأت في إضافة العقد الفرعية للعقد التي أعود إليها حاليًا. هل هناك طريقة للحلق من خلال جميع مستويات العقد الفرعية في ملف XML ، حتى لو لم أكن أعرف عدد المستويات الموجودة ، وأضفها إلى قائمتي؟
المحلول
لذا فإن ما عليك القيام به في الأساس هو وظيفة تأخذ كل منها <asset/>
طفل من العقدة الحالية ، يبني HTML ثم يتحقق مما إذا كانت العقدة الحالية تحتوي <asset/>
الأطفال من تلقاء نفسه ويحافظون على أعمق أسفل الشجرة.
إليك كيف يمكنك أن تفعل ذلك:
function printAssetMap()
{
return printAssets(simplexml_load_file(X_ASSETS));
}
function printAssets(SimpleXMLElement $parent)
{
$html = "<ul>\n";
foreach ($parent->asset as $asset)
{
$html .= printAsset($asset);
}
$html .= "</ul>\n";
return $html;
}
function printAsset(SimpleXMLElement $asset)
{
$html = '<li id="asset'.$asset->asset_assetid.'"><ins> </ins><a href="#">'.$asset->asset_name.' ['.$asset->asset_assetid.']</a>';
if (isset($asset->asset))
{
// has <asset/> children
$html .= printAssets($asset);
}
$html .= "</li>\n";
return $html;
}
بالمناسبة ، أتوقع وظيفة تدعى "printx" في الواقع مطبعة أو صدى شيء ما ، بدلاً من إعادته. ربما يجب عليك تسمية هذه الوظائف "buildx"؟
نصائح أخرى
تحتاج إلى استخدام وظيفة متكررة. فيما يلي مثال على إخراج صفيف من XML. إنه من مستندات PHP - http://www.php.net/manual/en/ref.simplexml.php. يمكنك تعديل هذا لإخراج قائمة.
<?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;
}
}
?>
<?php
function all_nodes($xml){
$all=array();
function add($node){
array_push($all,$node);
foreach($node as $child){
add($child);
}
}
add($xml->documentElement);
return $all;
}
?>
سيؤدي هذا إلى إرجاع مجموعة مع جميع العقد في المستند.