How to echo a DOMNodeList Object and a DOMElement Object? - php

I am using a loop to populate an array called $list. it is working like a charm..
// $content is a DOMNodeList Object
// $value is a DOMElement Object
$list = array();
foreach ($content as $value){
array_push($list, 'title'=>$value->nodeValue);
}
Eventhough my loop is populating my array correctly, I would like to digg into that DOM thing a little more to understand things better (this DOM thing is to new to me...). So what I would like, is to see how the DOMNodeList Object ($content) and DOMElement Object ($value) looks like.
So my question is simple: how can I "echo-out" those 'elements'?

Better than "echo-out" DomElement, read the documentation: http://php.net/manual/en/class.domelement.php.
If you want to see XML representation, use http://www.php.net/manual/en/domnode.c14n.php,
i.e.
echo $value->c14N(false,true);

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

PHP JSON or Array to XML

Whats the easiest way to take a JSON or Array object and convert it to XML. Maybe I am looking in all the wrong places but I am not finding a decent answer to get me on track with doing it. Is this something I would have to somehow build myself? Or is there something like json_encode/json_decode that will take an array or json object and ust pop it out as a xml object?
Here is my variant of JSON to XML conversion.
I get an array from JSON using json_decode() function:
$array = json_decode ($someJsonString, true);
Then I convert the array to XML with my arrayToXml() function:
$xml = new SimpleXMLElement('<root/>');
$this->arrayToXml($array, $xml);
Here is my arrayToXml() function:
/**
* Convert an array to XML
* #param array $array
* #param SimpleXMLElement $xml
*/
function arrayToXml($array, &$xml){
foreach ($array as $key => $value) {
if(is_int($key)){
$key = "e";
}
if(is_array($value)){
$label = $xml->addChild($key);
$this->arrayToXml($value, $label);
}
else {
$xml->addChild($key, $value);
}
}
}
Check it here: How to convert array to SimpleXML
and this documentation should help you too
Regarding Json to Array, you can use json_decode to do the same!
I am not sure about the easiest way. Both are relatively simple enough as I see it.
Here's a topic covering array to xml - How to convert array to SimpleXML and many pages covering json to xml can be found on google so I assume it's pretty much a matter of taste.

How to iterate over an array of stdObject elements in PHP?

This is the print_r() version of a data structure that I need to access via a foreach loop:
stdClass Object
(
[DetailedResponse] => Array
(
[0] => stdClass Object
( ...
)
[1] => stdClass Object
(
...
Now, how do I iterate though these objects?
I can sense that I should be doing something like this:
$object->DetailedResponse[0];
$object->DetailedResponse[1];
But how do I put it in a foreach type loop!!
seems like there are multiple objects in that obj.. you might need to do more foreach loops..
this code should get you the first sessionId in that obj.
foreach ($detailedresponses as $detailedresponse) {
foreach ($detailedresponseas as $response) {
echo $response->sessionId;
}
}
run this code to see the obj in a clearer way:
echo '<pre>'; print_r($detailsresponses); exit;
replace '$detailedresponses' with your correct variable name and post it back here, it should make things easier to read.
EDIT
check out this URL, I put my test data in there:
http://pastie.org/1130373
I recreated the object you're getting and put comments in there so you can understand what's happening :)
AND, you can get the properties like this:
echo $object->DetailedResponse[0]->sessionId;
very simple. you have a so called standard-object of php.
it's accessable like any other object in php by the $object->property syntax
so you can iterate over it this way:
foreach($object as $property), or foreach($object as $prop_name => $prop_val)
where you can access the properties by $object->$prop_name.
If you want to save a class, for re-using it later, you'd better to use serialize and unserialize()
Got a good solution to this - had a stdClass that contained other stdClases and arrays
function cleanEveryElement($someStdClass) {
foreach ($someStdClass as &$property) {
if ($property instanceof stdClass || is_array($property)) {
$property = cleanEveryElement($property);
}
else {
// Perform some function on each element, eg:
$property = trim($property);
}
}
return $someStdClass;
}

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);

adding data into json with PHP

i used json_decode to create a json object. After going through some elements i would like to add child elements to it. How do i do this?
Depending on which options you passed to json_decode(), you got either an object or array back from it, and you can add elements to these as you would any other object or array.
To add $key => $element to an array:
$myArray[$key] = $element;
Slightly less obvious, but you can add a new public member to an object in PHP as follows:
$myObj->$key = $element;
This will add a member variable from the contents of $key (assuming $key is a string).
If you then pass your array/object into json_encode(), you'll end up with the following json:
{ 'value_of_key' : 'value_of_element' }
I would use json_decode($json,true) with the true flag so that it would come back as an associative array. Then you can add items using the array syntax.

Categories