How to parse this XML file with PHP - php

I need to parse the following XML file below:
https://www.performanceexchange.com/publisher/report/api/17adeb41da1343209a32e6790ee1a286/xml/report/stats?startDate=2012-07-01&endDate=2012-08-13
$xml = simplexml_load_file( urlencode($mediatrust_url) );
Which outputs:
SimpleXMLElement Object
(
[#attributes] => Array
(
[name] => StatsReport
)
)
So it seems that it just picks up the name of the first tag.

Try this:
foreach($xml->attributes() as $k => $v)
{
if($k == "name")
{
//do something
}
}
Also, try using loading the XML string like this:
$sxml = simplexml_load_string(#file_get_contents($url));

Related

Access 0 index xml property in php

I have written a program which read an XML file and provide me an array. So I further perform my operations but I am not able to get the value of 0 index.
$xml = simplexml_load_file("app_string.xml");
foreach ($xml as $value) {
echo "<pre>";
print_r($value);
}
That is the output:
SimpleXMLElement Object (
[#attributes] => Array
(
[name] => app_name
)
[0] => My Data )
I tried with
$value->{0}
and
$value['0']
Not getting the desire data.
How can I get My Data from [0] => My Data
To retrieve the element data, you can simple cast the XML element to a string, as in:
$xml = simplexml_load_file("app_string.xml");
foreach ($xml as $value) {
echo "<pre>";
$data = (string)$value;
echo $data;
}

SimpleXmlElement count

I'm trying to count the amount of children in a SimpleXmlElement. I've searched on StackOverflow but I can't seem to find anything;
$xml = simplexml_load_string($xml);
foreach($xml as $key => $field) {
if (count($field) == 0){
$field[0][0] = 'test';
}
}
Some of my XmlElement are empty. Yet count gives 0 on all the elements. The only way I've found to do what I want is this:
if ($field[0][0] == '')
I've tried using $field->count() as specified on http://php.net/manual/en/simplexmlelement.count.php, but no matter what is in $field, it always returns 0.
Isn't there a better way to do this?
Here is the format of the xml through print_r:
SimpleXMLElement Object
(
[firstName] => Test
[lastName] => Test2
[middleName] => SimpleXMLElement Object
(
)
)
You can use the count() function like this:
$elem = new SimpleXMLElement($xml);
$elem->count();
http://php.net/manual/en/simplexmlelement.count.php for reference.

Extracting data from xpath reference of SimpleXMLElement Object

I'm trying to read an XML file into an array and I'm having a little bit of trouble. Here is what my code looks like so far:
$inst = new SimpleXMLElement($xml);
foreach( $inst->xpath("record[#id='" . $range . "']") as $u ) {
foreach($fields as $field) {
$results[$field] = $u->$field;
}
}
But when I do print_r($results), this is what's outputted:
Array
(
[field1] => SimpleXMLElement Object
(
[0] => field1Data
)
[field2] => SimpleXMLElement Object
(
[0] => field2Data
)
[field3] => SimpleXMLElement Object
(
[0] => field3Data
)
)
How can I get the data straight from the SimpleXMLElement Object and store it in the array rather than having it do this? I tried accessing it as an array like $u->$field[0] but that didn't work either.
Casting a SimpleXMLElement to string is the general solution(see "Forcing a SimpleXML Object to a string, regardless of context" for the canonical question), for a complete array containing all SimpleXMLElements like returned by xpath() or like you create it your own, a common way is to map the array onto trim:
$results = array_map('trim', $results);
or strval:
$results = array_map('strval', $results);
For example:
$inst = new SimpleXMLElement($xml);
list($u) = $inst->xpath("record[#id='" . $range . "']")
foreach ($fields as $field) {
$results[$field] = $u->$field;
}
$results = array_map('strval', $results);

Can I find selected options in a form using simplexml?

I'm able to find a select's options on a website using the following code:
$dom = new DOMDocument();
$dom->loadHTMLFile('http://webseven.com.au/carl/testpage.htm');
$xml = simplexml_import_dom($dom);
//print_r($xml);
$select = $xml->xpath('//table/tr/td/select');
print_r($select);
I get (as an example)
[0] => SimpleXMLElement Object
(
[#attributes] => Array
(
[name] => product_OnWeb
[tabindex] => 4
)
[option] => Array
(
[0] => Yes
[1] => No
)
)
But I cannot find a way to find which of those is selected. Can this be done with SimpleXML or is there another method?
You need to loop through all the options (using foreach ( $node->option ... )), and check for the selected attribute (using $node['selected']):
$dom = new DOMDocument();
$dom->loadHTMLFile('http://webseven.com.au/carl/testpage.htm');
$xml = simplexml_import_dom($dom);
$selects = $xml->xpath('//table/tr/td/select');
foreach ( $selects as $select_node )
{
echo $select_node['name'] . ': ';
foreach ( $select_node->option as $option_node )
{
if ( isset($option_node['selected']) )
{
echo $option_node['value'] . ' ';
}
}
echo "\n";
}
As an aside, you are likely to be led astray if you use print_r to debug SimpleXML, as it doesn't show you the true state of the object. I've written a simplexml_dump function which might be more useful.

php xpath problems

I'm doing a cURL POST and get the error response back, parse it into an array but having issues with xpath now.
// XML
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<errors xmlns="http://host/project">
<error code="30" description="[] is not a valid email address."/>
<error code="12" description="id[] does not exist."/>
<error code="3" description="account[] does not exist."/>
<error code="400" description="phone[] does not exist."/>
</errors>
// Function / Class
class parseXML
{
protected $xml;
public function __construct($xml) {
if(is_file($xml)) {
$this->xml = simplexml_load_file($xml);
} else {
$this->xml = simplexml_load_string($xml);
}
}
public function getErrorMessage() {
$in_arr = false;
$el = $this->xml->xpath("//#errors");
$returned_errors = count($el);
if($returned_errors > 0) {
foreach($el as $element) {
if(is_object($element) || is_array($element)) {
foreach($element as $item) {
$in_arr[] = $item;
}
}
}
} else {
return $returned_errors;
}
return $in_arr;
}
}
// Calling function
// $errorMessage is holding the XML value in an array index
// something like: $arr[3] = $xml;
$errMsg = new parseXML($arr[3]);
$errMsgArr = $errMsg->getErrorMessage();
What I would like is all the error code and description attribute values
EDIT:
OK this is print_r($this->xml,true);
SimpleXMLElement Object
(
[error] => Array
(
[0] => SimpleXMLElement Object
(
[#attributes] => Array
(
[code] => 30
[description] => [] is not a valid email address.
)
)
[1] => SimpleXMLElement Object
(
[#attributes] => Array
(
[code] => 12
[description] => Id[12345] does not exist.
)
)
[2] => SimpleXMLElement Object
(
[#attributes] => Array
(
[code] => 3
[description] => account[] does not exist.
)
)
[3] => SimpleXMLElement Object
(
[#attributes] => Array
(
[code] => 400
[description] => phone[] does not exist.
)
)
)
)
for the life of me I can't figure out why I can get the code and description, any thoughts?
EDIT #2
Okay so I guess I will break it down.
I'm using cURL to POST a request to one of our servers, I parse out the HTTP response headers and xml (if xml is returned). each line in the header/xml I explode into an array. so if there is an error I see an extra index to the array. I then do something like this.
$if_err_from_header = $http_return_response[10];
// I know that index 10 is where if any the error message in xml is (the one posted above).
after that I do this:
$errMsg = new parseXML($if_err_from_header);
$errMsgArr = $errMsg->getErrorMessage();
still I can not get the code and description from the attributes in error, what am I missing?
EDIT #3
Okay why does this work?
$in_arr = false;
// This returns all the code attributes
$el = $this->xml->xpath("//#code");
# if $el is false, nothing returned from xpath(), set to an empty array
$el = $el == false ? array() : $el;
foreach($el as $element) {
$in_arr[] = array("code" => $element["code"], "description" => $element["description"]);
}
return $in_arr;
EDIT #4:
Okay this gets that values I want but it's kinda a hack, would like to select specific elements but...
$el = $this->xml->xpath("//*");
Make sure you take the namespace into account:
$this->xml->registerXPathNamespace('n', 'http://host/project');
$el = $this->xml->xpath("/n:errors/n:error");
$returned_errors = count($el);
And example of accessing values for lower down..
foreach($el as $element) {
print "code: " . $element["code"] . "\n";
}
# in XPath is the attribute selector. You're trying to select the root element so it should be:
$el = $this->xml->xpath("/errors");
If you want to select all error elements, use
$el = $this->xml->xpath("/errors/error");
or
$el = $this->xml->xpath("//error");

Categories