iT邦幫忙

0

JSON表單,轉xml

請問我想把表單中的
First name Last name Phone Email,四個的值擷取出來,轉乘xml
像這樣只擷取JSON字串的幾個字

http://ithelp.ithome.com.tw/upload/images/20160824/201027328fptrN9itS.jpg
去掉 total到record:false 這串字
目前已可讀出->First name: Last name: Phone: Email:的值

function getSelections()
{


var data=$('#dg').datagrid("getData");
var json=JSON.stringify(data);
alert(json);


var msg=data.rows.reduce(function(pre,cur){
return pre+ 'Firstname:'+cur.firstname+'  Lastname:'+cur.lastname+'  phone:'+cur.phone+'  Email:' +cur.email+'\n';},'');
alert(msg);

}

請問接下來如何把值轉成JSON格式呢?
因為最後要再轉成xml如下

<Myxml>
   <data>
     <firstname>f</firstname>
     <lastname>f</lastname>
     <phone>efrf</phone>
     <email>d@d.d</email>
   </data>
   <data>
     <firstname>f</firstname>
     <lastname>f</lastname>
     <phone>efrf</phone>
     <email>d@d.d</email>
  </data> 
</Myxml>

1 個回答

5
fillano
iT邦超人 1 級 ‧ 2016-08-24 11:31:28
最佳解答

又被通知了XD

寫一個簡單的function可能比較快:

function j2x(o, opt) {
    var root = opt.root ? opt.root : 'root';
    var data = opt.data ? opt.data : 'data';
    var head = opt.head ? opt.head : false;
    if(!Array.isArray(o)) o = [o];
    var lead = '';
    if(head) lead = '<?xml version="1.0" encoding="UTF-8"?>\n';
    lead += '<' + root + '>\n';
    return o.reduce(function(pre, cur) {
        return pre + Object.keys(cur).reduce(function(p, c) {
            return p + '\t\t<' + c + '>' + cur[c] + '</' + c + '>\n';
        }, '\t<' + data + '>\n') + '\t</' + data + '>\n';
    }, lead) + '</' + root + '>';
}

簡單的使用範例:

var data = [
    {
        name: 'name 1',
        phone: 'phone 1'
    },
    {
        name: 'name 2',
        phone: 'phone 2',
    },
    {
        name: 'name 3',
        phone: 'phone 3'
    }
];

console.log(j2x(data, {root:'MyXml', data: 'data', head: true}));

結果:

<?xml version="1.0" encoding="UTF-8"?>
<MyXml>
	<data>
		<name>name 1</name>
		<phone>phone 1</phone>
	</data>
	<data>
		<name>name 2</name>
		<phone>phone 2</phone>
	</data>
	<data>
		<name>name 3</name>
		<phone>phone 3</phone>
	</data>
</MyXml>

這是針對你的需求寫的,並不是通用的作法。(通用的需要寫一個物件的parser,比較複雜。另外,這個也沒支援tag屬性)

看更多先前的回應...收起先前的回應...

費大很忙
/images/emoticon/emoticon76.gif

請問用eval來作的方法可行嗎?

fillano iT邦超人 1 級 ‧ 2016-08-24 18:53:37 檢舉

先看一下mdn上關於evel的說明:eval() ,後面有關於避免使用的建議。簡單說,應該沒有你非得用eval不可的理由才對...

沒有可不可行的問題,只要結果符合需求...所以是在你的場景是否需要使用它的問題。Javascript界避免使用eval的建議大概有十年以上了吧?所以請你先確定沒有其他方法可用XD

不好意思初學新手,可以問一下變數root等於後這段的意思嗎?
var root = opt.root ? opt.root : 'root';

目前只差在要如何去掉total到record:false 這串字
http://ithelp.ithome.com.tw/upload/images/20160825/20102732CzjoRbOu3l.jpg

我的做法是這樣

function ObjectToXml()
{

var data=$('#dg').datagrid("getData");

var json=JSON.stringify(data);
alert(json);


var xotree=new XML.ObjTree();

var xml;


var object=jQuery.parseJSON(json);

xml=xotree.writeXML(object);
alert(xml);
//document.getElementById("XML").value=xml;

}
fillano iT邦超人 1 級 ‧ 2016-08-25 14:17:55 檢舉

更精簡是

var root = opt.root | 'root';

簡單地說就是預設值。如果沒有透過opt傳進設定值,就使用預設值的意思。...還是說你的問題在於三元運算子?(X ? Y : Z)

fillano iT邦超人 1 級 ‧ 2016-08-25 14:24:13 檢舉

你不用去掉阿,而且data就是你要的東西,不必再靠jquery轉回物件。

如果你知道要用哪些key取出值,你根本不需要用到Object.keys,自己設一個key的陣列就好了。反過來說,你也可以用一個陣列來排除,只是這樣就需要在Object.keys(cur).reduce(function(p,c){這裡}...做過濾。

全部的code我放上來

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Build CRUD DataGrid with jQuery EasyUI - jQuery EasyUI Demo</title>
    <link rel="stylesheet" type="text/css" href="./easyui/themes/default/easyui.css">
    <link rel="stylesheet" type="text/css" href="./easyui/themes/icon.css">
    <link rel="stylesheet" type="text/css" href="./easyui/demo/demo.css">
    <script type="text/javascript" src="./jquery.min.js"></script>
    <script type="text/javascript" src="./jquery.easyui.min.js"></script>
    <script type="text/javascript" src="./jquery.edatagrid.js"></script>
    <script type="text/javascript" src="./ObjTree.js"></script>
</head>

<body>
    
    <p></p>
    <div style="margin:10px 0 40px 0;"></div>
     <a href="#" class="easyui-linkbutton" onclick="getSelected()">Catch</a>
 <a href="#" class="easyui-linkbutton" onclick="getSelections()">All</a>
<a href="#" class="easyui-linkbutton" id="JSON" onclick="ObjectToXml()">To Xml</a>
    </div>  
    <div style="padding:5px 0;"></div>
    
</body>


<body>
    <h2>CRUD DataGrid</h2>
    <p>Double click the row to begin editing.</p>
    
    <table id="dg"  title="My Users" style="width:700px;height:250px" 
data-options="rownumbers:true,singleSelect:true"
            toolbar="#toolbar" pagination="true" idField="id"
            rownumbers="true" fitColumns="true" singleSelect="true">
        <thead>
            <tr>
                <th field="firstname" width="50" editor="{type:'validatebox',options:{required:false}}">First Name</th>
                <th field="lastname" width="50" editor="{type:'validatebox',options:{required:false}}">Last Name</th>
                <th field="phone" width="50" editor="{type:'validatebox',options:{required:false}}">Phone</th>
                <th field="email" width="50" editor="{type:'validatebox',options:{required:false,validType:''}}">Email</th>
            </tr>
        </thead>
    </table>
<br/>

	</div>
    <div id="toolbar">
        <a href="javascript:void(0)" class="easyui-linkbutton" iconCls="icon-add" plain="true" onclick="javascript:$('#dg').edatagrid('addRow')">New</a>
        <a href="javascript:void(0)" class="easyui-linkbutton" iconCls="icon-remove" plain="true" onclick="javascript:$('#dg').edatagrid('destroyRow')">Destroy</a>
        <a href="javascript:void(0)" class="easyui-linkbutton" iconCls="icon-save" plain="true" onclick="javascript:$('#dg').edatagrid('saveRow')">Save</a>
        <a href="javascript:void(0)" class="easyui-linkbutton" iconCls="icon-undo" plain="true" onclick="$('#dg').edatagrid('cancelRow')">Cancel</a>

    </div>
    


<script type="text/javascript">



function getSelected()
{

	
//read
var row=$('#dg').datagrid("getSelected");

if(row)
  {
alert("Firstname:"+row.firstname+"  Lastname: "+row.lastname+"  Phone: "+row.phone+"  Email:" +row.email);

  }

}
function getSelections()
{


var data=$('#dg').datagrid("getData");
var json=JSON.stringify(data);

alert(json);

var msg=data.rows.reduce(function(pre,cur)
{return pre+ 'Firstname:'+cur.firstname+'  Lastname:'+cur.lastname+'  phone:'+cur.phone+'  Email:' +cur.email+'\n';},'');
alert(msg)




}
function ObjectToXml()
{



var data=$('#dg').datagrid("getData");

var json=JSON.stringify(data);

var obj=new Object;



if(data)
{


obj.firstname= data.rows.reduce(function(pre,cur)
{return pre+ cur.firstname},'');


obj.lastname=data.rows.reduce(function(pre,cur)
{return pre+ cur.lastname},'');

obj.phone=data.rows.reduce(function(pre,cur)
{return pre+ cur.phone},'');


obj.email=data.rows.reduce(function(pre,cur)
{return pre+ cur.email},'');

}













var xotree=new XML.ObjTree();

var xml;


var object=jQuery.parseJSON(json);

xml=xotree.writeXML(object);
alert(xml);


}



//intial
   $(function()
  {

     $('#dg').edatagrid({
     });
        
 });
    </script>
    
</body>
</html>

http://ithelp.ithome.com.tw/upload/images/20160826/201027325giZJZxIIP.jpg

http://ithelp.ithome.com.tw/upload/images/20160826/201027323T9sD3seuH.jpg

不知是哪段code影響到會讓他列出total~false這串

一般不是都沒有嗎
像這樣
http://ithelp.ithome.com.tw/upload/images/20160826/20102732wyNjIQHz7j.jpg

fillano iT邦超人 1 級 ‧ 2016-08-26 17:11:56 檢舉

我用官網的 Basic CRUD Application 做例子。

加上一個Export Users按鈕:

    <div id="toolbar">
		......
        <a href="javascript:void(0)" class="easyui-linkbutton" iconCls="icon-remove" plain="true" onclick="destroyUser()">Remove User</a>
        <a href="javascript:void(0)" class="easyui-linkbutton" iconCls="icon-print" plain="true" onclick="exportUser()">Export Users</a>
    </div>

然後加上程式把資料轉成xml:

function exportUser() {
	var data = $('#dg').datagrid('getData');
	var s = j2x(data.rows.map(function(item) {return {lastname:item.lastname,firstname:item.firstname,phone:item.phone,email:item.email};}), {root: 'Myxml'});
	alert(s);
}

function j2x(o, opt) {
    var root = opt.root ? opt.root : 'root';
    var data = opt.data ? opt.data : 'data';
    var head = opt.head ? opt.head : false;
    if(!Array.isArray(o)) o = [o];
    var lead = '';
    if(head) lead = '<?xml version="1.0" encoding="UTF-8"?>\n';
    lead += '<' + root + '>\n';
    return o.reduce(function(pre, cur) {
        return pre + Object.keys(cur).reduce(function(p, c) {
            return p + '\t\t<' + c + '>' + cur[c] + '</' + c + '>\n';
        }, '\t<' + data + '>\n') + '\t</' + data + '>\n';
    }, lead) + '</' + root + '>';
}

用的是我上面寫的方法。然後輸出像這樣:

http://ithelp.ithome.com.tw/upload/images/20160826/20000108dBfmX2yHjk.png

http://ithelp.ithome.com.tw/upload/images/20160826/20000108l6gYB4HXK2.png

fillano iT邦超人 1 級 ‧ 2016-08-26 17:14:46 檢舉

你要輸出的東西,應該是上例中的data.rows,然後為了只輸出lastname, firstname, phone, email這四個欄位,我用Array.map()來組出新的物件。

費大我有用出來,是用你之前call back function 可是怎麼換行呢? 打兩列以上就會連在一起

function ObjectToXml()
{



var data=$('#dg').datagrid("getData");

var json=JSON.stringify(data);

var obj=new Object;


//get 4 question answer
if(data)
{


obj.firstname= data.rows.reduce(function(pre,cur)
{return pre+ cur.firstname},'');


obj.lastname=data.rows.reduce(function(pre,cur)
{return pre+ cur.lastname},'');

obj.phone=data.rows.reduce(function(pre,cur)
{return pre+ cur.phone},'');


obj.email=data.rows.reduce(function(pre,cur)
{return pre+ cur.email},'');

}

//json String
var j={"firstname":""+obj.firstname,"lastname":""+obj.lastname,"phone":""+obj.phone,"email":""+obj.email};

alert(JSON.stringify(j));





//TO XML
var xotree=new XML.ObjTree();

var xml;


var object=jQuery.parseJSON(JSON.stringify(j));

xml=xotree.writeXML(object);
alert(xml);
//document.getElementById("XML").value=xml;

}


fillano iT邦超人 1 級 ‧ 2016-08-26 18:09:52 檢舉

"\n" 或 '\n' 就可以換行。

我要發表回答

立即登入回答