reading the first value using simplexml - php

I am using simplexml to read all the child nodes successfully. But how do I read the "NumCrds"?
<ACCOUNT NumCrds="1">
<ACCNO>some Bank</ACCNO>
<CURRCODE>CAD</CURRCODE>
<ACCTYPE>00</ACCTYPE>
</ACCOUNT>
I have read it somewhere in the PHP manual but I am unable to find it now.
$my_num_cards=$sxe->ACCOUNT['NumCrds'];
This is printing the number 1 for all the records even if there are values like 2, 3 in the file.

Attributes can be accessed using array indexes:
$data = '<ACCOUNT NumCrds="1">
<ACCNO>some Bank</ACCNO>
<CURRCODE>CAD</CURRCODE>
<ACCTYPE>00</ACCTYPE>
</ACCOUNT>
';
$xml = new SimpleXMLElement($data);
// this outputs 1
echo $xml['NumCrds'];
It is also possible to use the SimpleXMLElement::attributes() function to returns a list of all of the attribute key/value pairs.
$attributes = $xml->attributes();
echo $attributes['NumCrds'];

Use either $attrs = $el->attributes(); echo $attrs['NumCrds'] or just echo $el['NumCrds']. Attributes are reflected as array elements, while sub-tags are reflected as object properties.

$my_num_cards=$item->attributes()->NumCrds;
This is what I was looking for. Thanks for all your help.
http://fr.php.net/manual/en/simplexmlelement.attributes.php#94433

Related

In the second foreach loop strpos not working proberly [duplicate]

Let's say I have some XML like this
<channel>
<item>
<title>This is title 1</title>
</item>
</channel>
The code below does what I want in that it outputs the title as a string
$xml = simplexml_load_string($xmlstring);
echo $xml->channel->item->title;
Here's my problem. The code below doesn't treat the title as a string in that context so I end up with a SimpleXML object in the array instead of a string.
$foo = array( $xml->channel->item->title );
I've been working around it like this
$foo = array( sprintf("%s",$xml->channel->item->title) );
but that seems ugly.
What's the best way to force a SimpleXML object to a string, regardless of context?
Typecast the SimpleXMLObject to a string:
$foo = array( (string) $xml->channel->item->title );
The above code internally calls __toString() on the SimpleXMLObject. This method is not publicly available, as it interferes with the mapping scheme of the SimpleXMLObject, but it can still be invoked in the above manner.
You can use the PHP function
strval();
This function returns the string values of the parameter passed to it.
There is native SimpleXML method SimpleXMLElement::asXML
Depending on parameter it writes SimpleXMLElement to xml 1.0 file or just to a string:
$xml = new SimpleXMLElement($string);
$validfilename = '/temp/mylist.xml';
$xml->asXML($validfilename); // to a file
echo $xml->asXML(); // to a string
Another ugly way to do it:
$foo = array( $xml->channel->item->title."" );
It works, but it's not pretty.
The accepted answer actually returns an array containing a string, which isn't exactly what OP requested (a string).
To expand on that answer, use:
$foo = [ (string) $xml->channel->item->title ][0];
Which returns the single element of the array, a string.
To get XML data into a php array you do this:
// this gets all the outer levels into an associative php array
$header = array();
foreach($xml->children() as $child)
{
$header[$child->getName()] = sprintf("%s", $child);
}
echo "<pre>\n";
print_r($header);
echo "</pre>";
To get a childs child then just do this:
$data = array();
foreach($xml->data->children() as $child)
{
$header[$child->getName()] = sprintf("%s", $child);
}
echo "<pre>\n";
print_r($data);
echo "</pre>";
You can expand $xml-> through each level until you get what you want
You can also put all the nodes into one array without the levels or
just about any other way you want it.
Not sure if they changed the visibility of the __toString() method since the accepted answer was written but at this time it works fine for me:
var_dump($xml->channel->item->title->__toString());
OUTPUT:
string(15) "This is title 1"
Try strval($xml->channel->item->title)
There is native SimpleXML method SimpleXMLElement::asXML Depending on parameter it writes SimpleXMLElement to xml 1.0 file, Yes
$get_file= read file from path;
$itrate1=$get_file->node;
$html = $itrate1->richcontent->html;
echo $itrate1->richcontent->html->body->asXML();
print_r((string) $itrate1->richcontent->html->body->asXML());
Just put the ''. before any variable, it will convert into string.
$foo = array( ''. $xml->channel->item->title );
The following is a recursive function that will typecast all single-child elements to a String:
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// FUNCTION - CLEAN SIMPLE XML OBJECT
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function cleanSimpleXML($xmlObject = ''){
// LOOP CHILDREN
foreach ($xmlObject->children() as $child) {
// IF CONTAINS MULTIPLE CHILDREN
if(count($child->children()) > 1 ){
// RECURSE
$child = cleanSimpleXML($child);
}else{
// CAST
$child = (string)$child;
}
}
// RETURN CLEAN OBJECT
return $xmlObject;
} // END FUNCTION

How can i compare the values of the attributes on XML and only echo the attribute that contains the string i want with PHP?

So this is an example on how my XML looks like (I use SimpleXML and i would like to keep that way.).
<foo>
<foo1>
<energy A="false" B="false" C="false" D="true" E="false" F="false"/>
</foo1>
</foo>
This is my PHP so far:
$energyR = $xml->foo->foo1->energy[0]->attributes();
foreach($energy as $key => $ener){
echo $key, $ener;
}
The result is the following:
AfalseBfalseCfalseDtrueEfalseFfalse
Now what i want: To iterate through all the attributes and find which one is true and save ONLY the attribute that is true, to a variable.
That means that the result should be:
D (because this is the one which has the value of true)
Any ideas? A complete new code is acceptable too. As i mentioned, i use SimpleXML so please your answers only when it comes to SimpleXML.
foreach($energy as $key => $ener){
if ($ener == 'true') {
echo $key;
}
}
like this

SimpleXML, iteration on all element

I have a stock report file (coming from an outer source, therefore I can't modify in any way) and I would like to iterate over all elements (I have to save them into a MySQL table). As I see the $xml->Stockfile is an array of objects (2 items), so I tried to put it into an array.
For some reason the $myarray contains only the first element after the $myarray = $xml->StockFile assignment.
here is my code:
$xml = simplexml_load_file("../docs/stock.xml");
print_r($xml);
$myarray = $xml->StockFile;
print_r($myarray);
stock.xml:
<NewDataSet>
<StockFile>
<MatrixID>1533</MatrixID>
<Brand>myBrand</Brand>
<ProductCode>001</ProductCode>
<RRP>29.99</RRP>
<Image2Name />
<Image3Name />
</StockFile>
<StockFile>
<MatrixID>1534</MatrixID>
<Brand>myBrand</Brand>
<ProductCode>002</ProductCode>
<RRP>29.99</RRP>
<Image2Name />
<Image3Name />
</StockFile>
</NewDataSet>
Why I'm getting only one item instead of all?
What should I do do retrieve the whole array?
Take care with SimpleXMLElement. It has a lot of magic. Know the magic or get puzzled by print_r or var_dump or similar output. Your example extended:
$myarray = $xml->StockFile;
print_r($myarray); # shows one element
# foreach has both elements:
foreach($myarray as $name => $stockfile)
{
echo $name, ":\n", $stockfile->asXML(), "\n\n";
}
Even though it is the same variable ($myarray) it behaves differently depending on context it is used in. Inside a foreach the SimpleXMLElement (that is the type of that object) will provide an iterator over the child-elements named StockFile as specified here:
$myarray = $xml->StockFile;
However using that variable in some kind of single context, it will for example return the inner string of the first child-element with that name:
echo $myarray, "\n";
(which in your case is just some lines of whitespace).
See Demo: https://eval.in/83787
Running into this "trap" by SimpleXML is actually pretty common. I suggest to understand the basic usage by the example given in the manual:
Basic SimpleXML usage
change the last two lines to
foreach ($xml->StockFile as $nextStockFile) {
print_r ($nextStockFile);
}

Echo element from php array

Can someone tell me how I can loop through the below array?
http://pastebin.com/rhaF5Zdi
I've tried with out luck:
$_data = json_decode($_data);
foreach ( $_data as $tweet )
{
echo "{$tweet->text}\n";
}
thanks
ps: im follwoing this php script.
http://mikepultz.com/2013/06/mining-twitter-api-v1-1-streams-from-php-with-oauth/
hers another paste bin on the array. there seems to be multiple arrays happening
http://pastebin.com/dduzhpqY
It looks like you might be creating a PHP stnd object instead of an array
//this will create a php standard object
$objOfData=json_decode($json);
Instead Use the version below: (Notice the the 2nd parameter is TRUE)
$associativeArray=json_decode($json, TRUE);
This will turn the object into an associative array and you can access fields like so:
$id=$associativeArray['id'];
More info here: json_decode
The code in posted link is not JSON, but it is output of print_r() function. PHP has no invert function to print_r(), but on php.net in print_r() documentation's comments you can find some user-made functions which can read it.
For example this one:
http://www.php.net/manual/en/function.print-r.php#93529
I hope it will help. Good Luck :)
Ended up using:
if(array_key_exists('text', $_data)){
echo 'Tweet ID = '.$_data['id_str'];
echo 'Tweet Text = '.$_data['text'];
echo '<br /><br />';
}
cheers

How to view DOMNodeList object's data in php

when I want to test php array I use the following code
print_r($myarray);
but know I want to see the data of an object
my object is
$xpath = new DOMXPath($doc);
$myobject = $xpath->query('//*[ancestor-or-self::a]');
when I use
print_r($myobject);
I get that output
DOMNodeList Object ( )
I want to iterate through the values of this object to test the result of my query?
DOMNodeList is an interesting object, one that you will not get much information from using print_r or var_dump.
There are many ways to view the data of a DOMNodeList object. Here is an example:
$xpath = new DOMXpath($dom);
$dom_node_list = $xpath->query($your_xpath_query);
$temp_dom = new DOMDocument();
foreach($dom_node_list as $n) $temp_dom->appendChild($temp_dom->importNode($n,true));
print_r($temp_dom->saveHTML());
(Of course use saveXML instead of saveHTML if you are dealing with XML.)
A DOMNodeList can be iterated over like an array. If you want to pull the data out of the DOMNodeList object and put it into a different data structure, such as an array or stdClass object, then you simply iterate through the "nodes" in the DOMNodeList, converting the nodes' values and/or attributes (that you want to have available) before adding them to the new data structure.
It's possible to navigate through the nodes by using a simple foreach as follow:
foreach ($myobject as $node) {
echo $node->nodeValue, PHP_EOL;
} // end foreach
Hope that it can help others, the important pieces of code are the
foreach
and the item
$node->nodeValue
for more details regarding this class please visit:
http://php.net/manual/en/class.domnodelist.php
Someone wrote a great getArray() function:
http://www.php.net/manual/en/class.domdocument.php#101014
Your xpath query is not matching anything in your XML.
From the DomXPath::query manual page:
Returns a DOMNodeList containing all
nodes matching the given XPath
expression . Any expression which do
not return nodes will return an empty
DOMNodeList.
How about a recursive function?
Function XMLPrint_r($d_DomNode) {
print $d_DomNode->$nodeName." ".$d_DomNode->$nodeValue."<br>";
Foreach($d_DomNode->$childNodes as $d_ChildNode) {
print " ";
XMLPrint_r($d_ChildNode);
}
}
I did not test this, but you get the idea.
For some reason, I've been unable to get the saveHTML/saveXML methods to work. So I wrote my own recursive routine which works for me:
function pvIndent ( $ind ) {
for ($i=0;$i<$ind;$i++)
print ( " " );
}
function pvPrint_r ( $val ) {
echo '<pre>';
print_r ( $val );
echo '</pre>';
}
function pvDOMNodeListPrint_r_ ( $ind,$DOMNodeList ) {
for ($item=0;$item<$DOMNodeList->length;$item++) {
$DOMNode = $DOMNodeList->item($item);
if ($DOMNode->nodeName != "#text") {
pvIndent ( $ind );
print $DOMNode->nodeName;
if ($DOMNode->nodeValue)
print " = " . trim($DOMNode->nodeValue);
print "\n";
if ($DOMNode->attributes)
for ($attr=0;$attr<$DOMNode->attributes->length;$attr++) {
$DOMNodeAttr = $DOMNode->attributes->item($attr);
pvIndent ( $ind+1 );
print "#" . $DOMNodeAttr->nodeName . " = " . trim($DOMNodeAttr->nodeValue) . "\n";
}
if ($DOMNode->childNodes)
pvDOMNodeListPrint_r_ ( $ind+1,$DOMNode->childNodes );
}
}
}
function pvDOMNodeListPrint_r ( $DOMNodeList ) {
echo '<pre>';
pvDOMNodeListPrint_r_ ( 0,$DOMNodeList );
echo '</pre>';
}
Call pvDOMNodeListPrint_r with your result from a query on an XDOMPath object.
Notes :
pv is just the prefix I use to avoid name space pollution - feel free to edit it out.
pre tags are used so white space and newlines are handle properly for formatting when output in the body of your html, which is where I generally need such debugging statements - you can format to your taste.
I've explicitly skipped DOMNode's with the name "#text" as these seem to repeat the text already contained in the parent node. I'm not sure this correct for all valid XDOMPath's loaded with HTML, but I've not yet seen an exception - you can always eliminate the exclusion if you don't mind the usual redundancy.
A bit late in the game, but perhaps it helps someone...
Be aware of utf-8 output when using the dom/xpath object itself.
If you would output the nodeValue directly, you would get corrupted characters e.g.:
ìÂÂì ë¹Â디ì¤
ìì ë¹ë””ì¤ í°ì íì¤
You have to load your dom object with the second param "utf-8", new \DomDocument('1.0', 'utf-8'), but still when you print the dom node list/element value you get broken characters:
echo $contentItem->item($index)->nodeValue
you have to wrap it up with utf8_decode:
echo utf8_decode($contentItem->item($index)->nodeValue)
//output: 者不終朝而會,愚者可浹旬而學
var_dump($myobject); may be what you're looking for
its a example of xml file load by xpath
my xml file name is 'test.xml'
<college>
<student>
<firstName>Azhar Uddin</firstName>
<lastName>Raihan</lastName>
<mobile>018*******</mobile>
<fatherName>alam uddin</fatherName>
<address>
<presentAddress title="notun" type="multiple">
<zila>Feni</zila>
<upzila>chhagalniya</upzila>
<post>3912</post>
</presentAddress>
<permanentAddress>
<zila>comilla</zila>
<upzila>sadar</upzila>
</permanentAddress>
</address>
</student>
</college>
now load it
$sxe=simplexml_load_file('test.xml');
$address = $sxe->xpath("student/address/presentAddress");
foreach($address as $addr)
{
foreach($addr as $key=>$val)
{
echo $key."=".$val,"<br>";
}
}
After much debugging I found out that all DOM objects are invisible to var_dump() and print_r(), my guess is because they are C objects and not PHP objects. So I tried saveXML(), which works fine on DOMDocument, but is not implemented on DOMElement.
The solution is simple (if you know it):
$xml = $domElement->ownerDocument->saveXML($domElement);

Categories