Jump to content

XML to nested array


LemonInflux

Recommended Posts

I've been looking, and this seems impossible to do simply.

 

Can I get a nice, neat nested array from XML? xml_parse_into_struct makes a horrible looking array ('open', 'close' and 'complete' keys just complicate things). simpleXML objects are slightly prettier, but difficult to negotiate as much of it is object, not array, based.

 

So is there a way to turn, say:

 

<client>
  <name>John</name>
  <likes>cookies</likes>
</client>
<client>
  <name>John</name>
  <likes>cookies</likes>
</client>

 

into

 

array (
  'client' => array (
    'name' => 'John'
    'likes' => 'cookies'
  ),
  'client' => array (
    'name' => 'John'
    'likes' => 'cookies'
  )
);

 

Without complex regex/functions?

----------------

Now playing: Hadouken! - Get Smashed Gate Crash

via FoxyTunes

Link to comment
Share on other sites

I'm getting an external feed (namely, the youtube standard feeds (such as http://gdata.youtube.com/feeds/api/standardfeeds/top_rated)). I then want to parse it into a nested array so that I can display the data in a more friendly way to the users.

 

----------------

Now playing: Hadouken! - What She Did

via FoxyTunes

Link to comment
Share on other sites

I think i'm trying to do precisely the same thing as you. I have come across a lot of similar scripts and http://www.tylerbutler.com/projects/Pages/ParsingXFDFinPHP.aspx seems to be one of the better ones.

 

The code i am using at the moment is:

 

class xItem {
var $xTitle;
var $xLink;
var $xDescription;
var $xUrl;
var $xLng;
var $xLat;

}

// general vars
$sTitle = "";
$sLink = "";
$sDescription = "";
$sUrl = "";
$sLng = "";
$sLat = "";

$arItems = array();

$itemCount = 0;

// rss url goes here
$lng=-0.126236;
$lat=51.500152;
$rad=500;
$trustedkey="5c289fd31415f9408bf803f7d7876e74";

$uFile = "http://trustedplaces.com/api/rest/place/geo/?lng=".$lng."&lat=".$lat."&rad=".$rad."&key=".$trustedkey;

/* BEGIN XML PROCESSING */
// XML Parser element start function

function startElement($parser, $name, $attrs) {

global $curTag;
//track the tag we are currently in
$curTag .= "^$name";



}

// XML Parser element end function
function endElement($parser, $name) { global $curTag;

// remove the tag we are ending from the "tag tracker"
$caret_pos = strrpos($curTag,'^');

$curTag = substr($curTag,0,$caret_pos);

}

// XML Parser characterData function

function characterData($parser, $data) {

// get the xml information first

global $curTag, $sTitle, $sLink, $sDescription, $sUrl, $sLng, $sLat;

$titleKey= "^PLACES^PLACE^NAME";
$linkKey = "^PLACES^PLACE^WEBSITE";
$descKey = "^PLACES^PLACE^DESCRIPTION";
$urlKey  = "^PLACES^PLACE^URL";
$lngKey  = "^PLACES^PLACE^LONGITUDE";
$latKey  = "^PLACES^PLACE^LATITUDE";

// we are in the value tag, so put the value in the array
if ($curTag == $titleKey) {
	$sTitle = $data;
}
elseif ($curTag == $linkKey) {
	$sLink = $data;
}
elseif ($curTag == $descKey) {
	$sDescription = $data;
}
elseif ($curTag == $urlKey) {
	$sUrl = $data;
}
elseif ($curTag == $lngKey) {
	$sLng = $data;
}
elseif ($curTag == $latKey) {
	$sLat = $data;
}

  // now get the items
  global $arItems, $itemCount;
  $itemTitleKey="^PLACES^PLACE^NAME";
  $itemLinkKey="^PLACES^PLACE^WEBSITE";
  $itemDescKey="^PLACES^PLACE^DESCRIPTION";
  $itemUrlKey= "^PLACES^PLACE^URL";
  $itemLngKey= "^PLACES^PLACE^LONGITUDE";
  $itemLatKey= "^PLACES^PLACE^LATITUDE";

if ($curTag == $itemTitleKey) {

// make new xItem
$arItems[$itemCount] = new xItem();

	// set new item objects properties
	$arItems[$itemCount]->xTitle = $data;
	}
	elseif ($curTag == $itemLinkKey) {
	$arItems[$itemCount]->xLink = $data;
	}
	elseif ($curTag == $itemDescKey) {
	$arItems[$itemCount]->xDescription = $data;
	}
	elseif ($curTag == $itemUrlKey) {
	$arItems[$itemCount]->xUrl = $data;
	}
	elseif ($curTag == $itemLngKey) {
	$arItems[$itemCount]->xLng = $data;
	}
	elseif ($curTag == $itemLatKey) {
	$arItems[$itemCount]->xLat = $data;
	}
	//increment item counter
	$itemCount++;
	}

// Create the parser and parse the file
$xml_parser = xml_parser_create();
xml_set_element_handler($xml_parser, "startElement", "endElement");
xml_set_character_data_handler($xml_parser, "characterData");

if (!($fp = fopen($uFile,"r"))) {
die ("could not open file for, nput");
}

while ($data = fread($fp, 4096)) {
$data = str_replace("&","[amp];",$data);

if (!xml_parse($xml_parser, $data, feof($fp))) {
	die(sprintf("XML error: %s at line %d", xml_error_string(xml_get_error_code($xml_parser)), xml_get_current_line_number($xml_parser)));
	}

}
xml_parser_free($xml_parser);

// write out the items

for ($i=0;$i<count($arItems);$i++) {

$txItem = $arItems[$i];

if (!empty($txItem->xLink)) echo("<a href=".$txItem->xLink.">".$txItem->xTitle."</a><br/>");

else echo("<h3>".$txItem->xTitle."</h3>");

if (!empty($txItem->xDescription)) echo ("<p>".$txItem->xDescription."</p>");

if (!empty($txItem->xUrl)) echo ("<p>".$txItem->xUrl."</p>");

if (!empty($txItem->xLng)) echo ("<p>".$txItem->xLng."</p>");

if (!empty($txItem->xLat)) echo ("<p>".$txItem->xLat."</p>");

}

?>

 

The problem i'm having at the moment is that i'm losing data half way through the script for descriptions, ... I know it's using objects, but as this seems to be the most widely used code for parsing XML. It will also deal with special characters as for some reason "&" breaks the parser.

 

I hope this helps, and any solutions to my problem would help out! :D

 

function startElement($parser, $name, $attrs)
{
    global $curTag, $field;
    
    //track the tag we're currently in
    $curTag .= "^$name";
    
    if( $curTag == "^XFDF^FIELDS^FIELD" )
    {
        //save the name of the field in a global var
        $field = $attrs['NAME'];
    }
}

 

If anybody can explain what the difference is and what the if statement is doing in this portion of Tyler Butler's code that might help me along too :)

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.