Currently working with this sort of json:
[
{
"title": "Ramones",
"authors": {
"6172": {
"lastname": "Ramone",
"firstname": "Joey",
},
"6768": {
"lastname": "Ramone",
"firstname": "Dee Dee",
}
}
}
]
And would like to display values as this:
Ramones Joey Ramone Dee Dee Ramone
The PHP code i use:
$arr = json_decode(file_get_contents("my-json-url"),true);
foreach($arr as $item) {
echo "<h1>".$item['title']."</h1>";
echo .$item['authors']['firstname'].$item['authors']['lastname'];
};
And as result i only get the title value, didn't know how to pass through the ID number.
Thanks for your help.
You can use a second foreach loop to loop through the authors of your item :
$arr = json_decode(file_get_contents("my-json-url"),true);
foreach($arr as $item) {
echo "<h1>".$item['title']."</h1>";
foreach($item['authors'] as $author)
{
echo "\n".$author['firstname']." ".$author['lastname'];
}
};
I also improved the authors output, so you get the wanted display.
Related
I am looking for a Powershell function to convert XML into a PsCustomObject which can finally exported as JSON. For this I created this small XML Test object:
[xml]$Xml = #"
<Action name="Test" id="1">
<Text>sample</Text>
<sub name="s1" id="2" />
<sub name="s2" id="3" />
<end details="no" />
</Action>
"#
This gives my an XML DocumentElement which I finally need to convert into the same object like the one from this call:
$Json = convertfrom-json #"
{
"Action": {
"name": "Test", "id": "1", "Text": "sample",
"sub": [
{"name": "s1","id": "2"},
{"name": "s2","id": "3"}
],
"End": {"details": "no"}
}
}
"#
Is there any smart way to get this done? I tested multiple functions from similar questions here but nothing really works as expected.
Because of the ambiguities, there is no standard way of converting XML to JSON. So you really have to roll your own function that interprets the XML in the way that matches your desired output.
Here is a generic solution:
Function ConvertFrom-MyXml( [xml.XmlNode] $node ) {
# Create an ordered hashtable
$ht = [ordered] #{}
# Copy the XML attributes to the hashtable
$node.Attributes.ForEach{ $ht[ $_.Name ] = $_.Value }
$node.ChildNodes.ForEach{
if( $_.FirstChild -is [xml.XmlText] ) {
# Add content of XML text node
Add-DictionaryArrayItem -Dict $ht -Key $_.LocalName -Value $_.FirstChild.InnerText
}
elseif( $_ -is [xml.XmlElement] ) {
# Add nested hashtable for the XML child elements (recursion)
Add-DictionaryArrayItem -Dict $ht -Key $_.LocalName -Value (ConvertFrom-MyXml $_)
}
}
$ht # Output
}
Function Add-DictionaryArrayItem( $Dict, $Key, $Value ) {
if( $Dict.Contains( $Key ) ) {
$curValue = $Dict[ $Key ]
# If existing value is not already a list...
if( $curValue -isnot [Collections.Generic.List[object]] ) {
# ...turn it into a list.
$curValue = [Collections.Generic.List[object]] #($curValue)
$Dict[ $Key ] = $curValue
}
# Add next value to the array. This updates the array in the hashtable,
# because $curValue is a reference.
$curValue.Add( $Value )
}
else {
# Key doesn't exist in the hashtable yet, so simply add it.
$Dict[ $Key ] = $Value
}
}
[xml]$Xml = #"
<Action name="Test" id="1">
<Text>sample</Text>
<sub name="s1" id="2" />
<sub name="s2" id="3" />
<end details="no" />
</Action>
"#
ConvertFrom-MyXml $Xml | ConvertTo-Json -Depth 100
Output:
{
"Action": {
"name": "Test",
"id": "1",
"Text": "sample",
"sub": [
{
"name": "s1",
"id": "2"
},
{
"name": "s2",
"id": "3"
}
],
"end": {
"details": "no"
}
}
}
Function ConvertFrom-MyXml outputs an ordered hashtable. There is no need to convert to PSCustomObject as ConvertFrom-Json works with hashtables as well. So we can keep the code simpler.
ConvertFrom-MyXml loops over attributes and elements (recursively) of the given XML node. It calls the helper function Add-DictionaryArrayItem to create an array if a key already exists in the hashtable. Actually this is not a raw, fixed-size array (like #(1,2,3) creates), but a dynamically resizable List, which behaves very similar to an array but is much more efficient when adding many elements.
Note that a single sub element won't be turned into an array. If some elements should always be converted to arrays, you'd have to pass some kind of schema to the function (e. g. a list of element names) or add metadata to the XML itself.
As suggested by OP, here is an alternative version of the code, that consists of only a single function:
Function ConvertFrom-MyXml( [xml.XmlNode] $node ) {
$ht = [ordered] #{}
$node.Attributes.ForEach{ $ht[ $_.Name ] = $_.Value }
foreach( $child in $node.ChildNodes ) {
$key = $child.LocalName
$value = if( $child.FirstChild -is [xml.XmlText] ) {
$child.FirstChild.InnerText
} elseif( $child -is [xml.XmlElement] ) {
ConvertFrom-MyXml $child
} else {
continue
}
if( $ht.Contains( $Key ) ) {
$curValue = $ht[ $Key ]
if( $curValue -isnot [Collections.Generic.List[object]] ) {
$curValue = [Collections.Generic.List[object]] #($curValue)
$ht[ $Key ] = $curValue
}
$curValue.Add( $Value )
}
else {
$ht[ $Key ] = $Value
}
}
$ht # Output
}
Might not be exactly what you're looking for but I would personally do this with classes:
class Sub {
[string] $Name
[Int] $Id
Sub([string] $Name, [int] $Id) {
$this.Name = $Name
$this.Id = $Id
}
}
# Windows PowerShell will not like it named End :)
class End2 {
[string] $Details
End2 ([string] $Details) {
$this.Details = $Details
}
}
class Action {
[string] $Name
[int] $Id
[string] $Text
[Sub[]] $Sub
[End2] $End
Action () { }
Action ([string] $Name, [int] $Id, [string] $Text, [object[]] $Sub, [End2] $End) {
$this.Name = $Name
$this.Id = $Id
$this.Text = $Text
$this.Sub = #( $Sub )
$this.End = $End
}
[string] ToJson() {
return #{ Action = $this } | ConvertTo-Json -Depth 99
}
}
Now you can instantiate and convert to to Json your Action class like this:
[Action]::new(
'Test', 1, 'Sample',
#(
[Sub]::new('s1', 2)
[Sub]::new('s2', 3)
),
'No'
).ToJson()
Or like this:
([Action]#{
Name = 'Test'
Id = 1
Text = 'Sample'
Sub = #(
[Sub]::new('s1', 2)
[Sub]::new('s2', 3)
)
End = 'No'
}).ToJson()
Both would output the following Json:
{
"Action": {
"Name": "Test",
"Id": 1,
"Text": "Sample",
"Sub": [
{
"Name": "s1",
"Id": 2
},
{
"Name": "s2",
"Id": 3
}
],
"End": {
"Details": "No"
}
}
}
Look at this
may help
class sub {
[string] $name;
[int] $id;
}
class end {
[string] $details;
}
class Action {
[string] $Text;
[sub] $sub1;
[sub] $sub2;
[end] $end;
[string] $name;
[int] $id;
}
<#
<Action name="Test" id="1">
<Text>sample</Text>
<sub name="s1" id="2" />
<sub name="s2" id="3" />
<end details="no" />
</Action>
#>
$firstitem = [Action]#{
text = 'sample';
name = "test";
id = "1";
sub1=#{
name = "s1";
id = "2";}
sub2 = #{
name = "s2";
id = "3";}
end = #{
details = "no";}
}
$firstitem | ConvertTo-Json
<#
Output =
{
"Text": "sample",
"sub1": {
"name": "s1",
"id": 2
},
"sub2": {
"name": "s2",
"id": 3
},
"end": {
"details": "no"
},
"name": "test",
"id": 1
}
#>
I have json files where the various fields can change.
"eventHistory": [{
"occurredAt": "2018-03-17T10:40:05.707 0000",
"calluuid": "G8EMGR6EKD7DLDRP79FOEONVQ4000031",
"eventId": "2018-03-17T10:40:05.707Z_1521283205_G8EMGR6EKD7DLDRP79FOEONVQ4000031",
"event": "Data",
"data": {
"added": {
"OtherTrunkName": "sbc-trunk",
"OriginationDN": "1234",
"BusinessCall": "0",
"OriginationDN_location": "MNLSwitch"
}
}
}, {
"occurredAt": "2018-03-17T10:40:06.033 0000",
"calluuid": "G8EMGR6EKD7DLDRP79FOEONVQ4000031",
"eventId": "2018-03-17T10:40:06.033Z_1521283206_G8EMGR6EKD7DLDRP79FOEONVQ4000031",
"event": "Data",
"data": {
"added": {
"IW_CaseUid": "04d575ba-32e3-48da-8986-a19a6ff493b3",
"IW_BundleUid": "bf3ac19e-e2ea-4d7b-9b48-ef5e17dfdaa1"
}
}
}, {
"occurredAt": "2018-03-17T10:40:10.407 0000",
"calluuid": "G8EMGR6EKD7DLDRP79FOEONVQ4000031",
"eventId": "2018-03-17T10:40:10.407Z_1521283210_G8EMGR6EKD7DLDRP79FOEONVQ4000031",
"event": "Data",
"data": {
"added": {
"WrapUpTime": "0"
},
"deleted": {
"OriginationDN_location": "MNLSwitch",
"OriginationDN": "1234"
}
}
},
Is there an 'easy' way to simply read through and add these as variables to a js. I gather each field and then post to PHP which saves.
then I need to display in a tree... another question likely to appear on that one too.
Any help much appreciated.
It is unclear if you require the variables to be declared in a JS file, or if you simply want each key and value pair to be extracted out. Thus, I've provided 2 approaches that could be useful for your use case.
Suggestion: If it doesn't matter, why not handle the whole JSON object in your PHP save script?
1. Extract Key Value pairs
If you require a recursive JS function to get all the keys and values, you may use this function, referenced from here.
Caveat: This function ignores keys with nested key value pairs, so you will need to modify it to suit your needs.
var json = `
{
"occurredAt": "2018-03-17T10:40:06.033 0000",
"calluuid": "G8EMGR6EKD7DLDRP79FOEONVQ4000031",
"eventId": "2018-03-17T10:40:06.033Z_1521283206_G8EMGR6EKD7DLDRP79FOEONVQ4000031",
"event": "Data",
"data": {
"added": {
"IW_CaseUid": "04d575ba-32e3-48da-8986-a19a6ff493b3",
"IW_BundleUid": "bf3ac19e-e2ea-4d7b-9b48-ef5e17dfdaa1"
}
}
}
`
var obj = JSON.parse(json);
iterate(obj,'');
function iterate(obj, stack) {
for (var property in obj) {
if (obj.hasOwnProperty(property)) {
if (typeof obj[property] == "object") {
iterate(obj[property], stack + '.' + property);
} else {
console.log(property + " " + obj[property]); //get key and value pair here
}
}
}
}
2. Declare Variables in JS
If you require variables to be declared in a JS <script> tag, you can consider using PHP to generate a HTML page with the variables declared.
The code below produces a html file with the following script tag:
Advantage: This approach allows you to get creative, and generate a lot of JS code that is variable specific.
Disadvantage: Debugging this could be hard.
Caveat: The example below is not recursive, so you'll have to do that on your own.
<?php
$string = <<<EOD
{
"occurredAt": "2018-03-17T10:40:06.033 0000",
"calluuid": "G8EMGR6EKD7DLDRP79FOEONVQ4000031",
"eventId": "2018-03-17T10:40:06.033Z_1521283206_G8EMGR6EKD7DLDRP79FOEONVQ4000031",
"event": "Data",
"data": {
"added": {
"IW_CaseUid": "04d575ba-32e3-48da-8986-a19a6ff493b3",
"IW_BundleUid": "bf3ac19e-e2ea-4d7b-9b48-ef5e17dfdaa1"
}
}
}
EOD;
$json = json_decode($string);
echo '<script>';
foreach($json as $key => $value)
{
$output = <<<EOD
var $key = "$value";
EOD;
echo $output;
}
echo '</script>';
?>
Below is the code for user list webservice's json response.
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class Webservice extends CI_Controller
{
function list_user()
{
$result_login = $this->db->get('user_registration')->result();
$response = array();
$response ["success"] = 1;
$response ["message"] = "User List.";
foreach($result_login as $row)
{
$data = array();
$data['User Id'] = $row->user_id;
$data['Name'] = $row->name;
$data['Email'] = $row->email;
$data['mobile_number'] = $row->mobile_number;
$data['Password'] = $row->password;
$output2 = json_encode(array('responsedata' => $data));
echo $output2;
}
}
}
?>
In my code if i replace $data with $response in json_encode then i can't get $data's value.
I got json response in this format. JSON Response.
{
"responsedata": {
"User Id": "7",
"Name": "bhavin",
"Email": "bhavin123#gmail.com",
"mobile_number": "123456789",
"Password": "abc"
}
}
But i want json response in this format.
{
"responsedata":
{
"success": 1,
"data": [
{
"User Id": "7",
"Name": "test",
"Email": "test1#gmail.com",
"mobile_number": "123456789",
"Password": "abc"
},
{
"User Id": "8",
"Name": "test2",
"Email": "test2#gmail.com",
"mobile_number": "123456789",
"Password": "abc"
}
]
}
}
You need to arrange Your array like this
I update below code
$array_of_event = array()
foreach($result_login->result_array() as $row)
{
$array_of_event[] = $row;
}
$data['success'] = "1";
$data['data'] = $array_of_event; //need to assign event here
$response['responsedata'] = $data;
echo json_encode($response);
I'm trying to get the value of username and id from the following output.
{
"listusersresponse": {
"count": 1,
"user": [
{
"id": "f01e8ea4-2da5-11e4-a846-726c7bbb864f",
"username": "admin",
"firstname": "admin",
"lastname": "test",
"created": "2014-08-26T20:52:24-0400",
"state": "enabled",
"account": "admin",
"accounttype": 1,
"domainid": "c091153a-2da5-11e4-a846-726c7bbb864f",
"accountid": "f01e7c02-2da5-11e4-a846-726c7bbb864f",
"iscallerchilddomain": false,
"isdefault": true
}
]
}
}
This is what I have tried
$url = file_get_contents("http://URL/client/&response=json");
$data = json_decode($url);
var_dump($data);
foreach ($data as $value) {
echo $value->count;
}
For this works and I get 1
However when trying to access "username"
foreach ($data as $value) {
echo $value->user->username;
}
I get the following error: Notice: Trying to get property of non-object in "filename"
User is an array.
foreach ($data as $value) {
echo $value->user[0]->username;
}
Not sure how your json looks with several users, It must be like this then I guess:
foreach ($data as $value) {
foreach ($value->user as $user) {
echo $user->username;
}
}
sorry if this is a dumb question. My problem is I want make a PHP file that parses in JSON the contents of a MySQL table. The problem is i have a field that have JSON in it with breaklines:
{
"6cb20a9f-27fa-4d98-ac2e-e959eb3f0f63": {
"file": "",
"title": "",
"link": "",
"target": "0",
"rel": ""
},
"43aa1b15-986e-4303-afcf-628b835f10e5": {
"0": {
"value": "<p>This is an example description.<\/p>"
}
},
"97dacf42-398b-45c5-8536-baec4250b27e": {
"0": {
"value": "2012-10-19 00:00:00"
}
},
"20fec805-ebb1-4045-9f3d-ea90ad952e91": {
"0": {
"value": "A restaurant"
}
}
}
So at the moment of using the PHP it looks like this:
PHP Fail
What can I do for it to avoid the \n and \t, because I'm sending this parse to an iphone app and it doesn't recognize it. Thanks!
The PHP Code is something like this:
<?php>
$link = mysql_pconnect("localhost", "root", "") or die("Could not connect");
mysql_select_db("test") or die("Could not select database");
$arr = array();
$rs = mysql_query("SELECT * FROM people");
while($obj = mysql_fetch_object($rs)) {$arr[] = $obj;
}
echo '{"members":'.json_encode($arr).'}';
?>