2016-08-18 2 views
2

В ColdFusion (REST/C, я пытаюсь заполнить структуру, называемую «магазины»). Вложенная внутри - массив отчетов и вложенная внутри отчетов - это массив изображений. вложенные внутри отчетов - это массив Вопросов, а вложенный в «Вопросы» - это массив ответов.Создание структуры JSON Coldfusion с вложенными массивами структур

ПРИМЕЧАНИЕ. В каждом магазине могут быть несколько отчетов, и каждый отчет может содержать несколько изображений, а также несколько вопросов, и каждый вопрос может иметь несколько ответов.

окончательный JSON должен выглядеть следующим образом ...

stores:[ 
{"storeid":"101","storename":"STORE101",reports:[ 
    {"reportid":"201","reportname":"REPORT201","pics":[ 
     {"picid":"301","pictitle":"SOMEPIC1"},{"picid":"302","pictitle":"SOMEPIC2"} 
    ],"questions":[ 
     {"questionid":"111","question":"What is your favorite color?","answers":[ 
      {"answerid":"555","answer":"Blue"},{"answerid":"556","answer":"Green"},{"answerid":"557","answer":"Red"} 
     ]},{"questionid":"222","question":"What is your favorite car?","answers":[ 
      {"answerid":"655","answer":"Ferrari"},{"answerid":"656","answer":"Mustang"},{"answerid":"657","answer":"Porsche"} 
     ]} 
    ]},{"reportid":"202","reportname":"REPORT202","pics":[ 
     {"picid":"304","pictitle":"SOMEPIC4"},{"picid":"305","pictitle":"SOMEPIC5"} 
    ],"questions":[ 
     {"questionid":"111","question":"What is your favorite color?","answers":[ 
      {"answerid":"555","answer":"Blue"},{"answerid":"556","answer":"Green"},{"answerid":"557","answer":"Red"} 
     ]},{"questionid":"222","question":"What is your favorite car?","answers":[ 
      {"answerid":"655","answer":"Ferrari"},{"answerid":"656","answer":"Mustang"},{"answerid":"657","answer":"Porsche"} 
     ]} 
    ]}, 
    ]},{"reportid":"203","reportname":"REPORT103","pics":[ 
     {"picid":"307","pictitle":"SOMEPIC7"},{"picid":"308","pictitle":"SOMEPIC8"} 
    ],"questions":[ 
     {"questionid":"111","question":"What is your favorite color?","answers":[ 
      {"answerid":"555","answer":"Blue"},{"answerid":"556","answer":"Green"},{"answerid":"557","answer":"Red"} 
     ]},{"questionid":"222","question":"What is your favorite car?","answers":[ 
      {"answerid":"655","answer":"Ferrari"},{"answerid":"656","answer":"Mustang"},{"answerid":"657","answer":"Porsche"} 
     ]} 
    ]}, 
{"storeid":"102","storename":"STORE102",reports:[ 
    {"reportid":"201","reportname":"REPORT201","pics":[ 
     {"picid":"301","pictitle":"SOMEPIC1"},{"picid":"302","pictitle":"SOMEPIC2"} 
    ],"questions":[ 
    ],"questions":[ 
     {"questionid":"111","question":"What is your favorite color?","answers":[ 
      {"answerid":"555","answer":"Blue"},{"answerid":"556","answer":"Green"},{"answerid":"557","answer":"Red"} 
     ]},{"questionid":"222","question":"What is your favorite car?","answers":[ 
      {"answerid":"655","answer":"Ferrari"},{"answerid":"656","answer":"Mustang"},{"answerid":"657","answer":"Porsche"} 
     ]} 
    ]},{"reportid":"202","reportname":"REPORT202","pics":[ 
     {"picid":"304","pictitle":"SOMEPIC4"},{"picid":"305","pictitle":"SOMEPIC5"} 
    ],"questions":[ 
     {"questionid":"111","question":"What is your favorite color?","answers":[ 
      {"answerid":"555","answer":"Blue"},{"answerid":"556","answer":"Green"},{"answerid":"557","answer":"Red"} 
     ]},{"questionid":"222","question":"What is your favorite car?","answers":[ 
      {"answerid":"655","answer":"Ferrari"},{"answerid":"656","answer":"Mustang"},{"answerid":"657","answer":"Porsche"} 
     ]} 
    ]}, 
    ,{"reportid":"203","reportname":"REPORT103","pics":[ 
     {"picid":"307","pictitle":"SOMEPIC7"},{"picid":"308","pictitle":"SOMEPIC8"} 
    ],"questions":[ 
     {"questionid":"111","question":"What is your favorite color?","answers":[ 
      {"answerid":"555","answer":"Blue"},{"answerid":"556","answer":"Green"},{"answerid":"557","answer":"Red"} 
     ]},{"questionid":"222","question":"What is your favorite car?","answers":[ 
      {"answerid":"655","answer":"Ferrari"},{"answerid":"656","answer":"Mustang"},{"answerid":"657","answer":"Porsche"} 
     ]} 
    ]}, 
    ]}, 
{"storeid":"103","storename":"STORE103",reports:[ 
    {"reportid":"201","reportname":"REPORT201","pics":[ 
     {"picid":"301","pictitle":"SOMEPIC1"},{"picid":"302","pictitle":"SOMEPIC2"} 
    ],"questions":[ 
     {"questionid":"111","question":"What is your favorite color?","answers":[ 
      {"answerid":"555","answer":"Blue"},{"answerid":"556","answer":"Green"},{"answerid":"557","answer":"Red"} 
     ]},{"questionid":"222","question":"What is your favorite car?","answers":[ 
      {"answerid":"655","answer":"Ferrari"},{"answerid":"656","answer":"Mustang"},{"answerid":"657","answer":"Porsche"} 
     ]} 
    ]}, 
    {"reportid":"202","reportname":"REPORT202","pics":[ 
     {"picid":"304","pictitle":"SOMEPIC4"},{"picid":"305","pictitle":"SOMEPIC5"} 
    ],"questions":[ 
     {"questionid":"111","question":"What is your favorite color?","answers":[ 
      {"answerid":"555","answer":"Blue"},{"answerid":"556","answer":"Green"},{"answerid":"557","answer":"Red"} 
     ]},{"questionid":"222","question":"What is your favorite car?","answers":[ 
      {"answerid":"655","answer":"Ferrari"},{"answerid":"656","answer":"Mustang"},{"answerid":"657","answer":"Porsche"} 
     ]} 
    ]}, 
    {"reportid":"203","reportname":"REPORT103","pics":[ 
     {"picid":"307","pictitle":"SOMEPIC7"},{"picid":"308","pictitle":"SOMEPIC8"} 
    ],"questions":[ 
     {"questionid":"111","question":"What is your favorite color?","answers":[ 
      {"answerid":"555","answer":"Blue"},{"answerid":"556","answer":"Green"},{"answerid":"557","answer":"Red"} 
     ]},{"questionid":"222","question":"What is your favorite car?","answers":[ 
      {"answerid":"655","answer":"Ferrari"},{"answerid":"656","answer":"Mustang"},{"answerid":"657","answer":"Porsche"} 
     ]} 
    ]}, 
    ]} 
] 

Вот код, с которым я сбой.

<!--- MY REPORTS (GET) ---> 
    <cffunction name="getmyreports" access="remote" returntype="any" produces="application/json" httpmethod="get" restpath="/myreports/{user_id}/{device_id}/{token}"> 
     <cfargument name="user_id" required="true" type="numeric" restargsource="path"/> 
     <cfargument name="device_id" required="true" type="string" restargsource="path"/> 
     <cfargument name="token" required="true" type="string" restargsource="path"/> 


<cfquery name="r" datasource="#this.dsn#"> 
    SELECT   rt.report_type_id, rt.report_type, rd.user_id, u.firstname, u.lastname, u.username, rn.priority, rn.start_date, rn.aid, 
          rn.report_id, rn.report_name, rn.exp_date, rn.report_num, 
          rn.pic_num, rn.report_type, rn.report_date, rn.est_hrs, 
          rd.report_id, rd.report_complete, rd.report_status, rd.complete_date, 
          rd.report_data_id, rd.comments, rd.resubmit, s.storeid, s.client_loc, s.city, s.state 
    FROM    report_types rt, users u, report_name rn, report_data rd, stores s 
    WHERE   u.user_id=rd.user_id 
    AND     rd.storeid=s.storeid 
    AND      rt.report_type_id=rn.report_type 
    AND     rn.report_id=rd.report_id 
    AND      rn.report_name_status = 1 
    <cfif auth.usertype eq 4>AND rn.report_type = 172</cfif><!--- audit only ---> 
    AND      rd.report_status = 0 <!--- not completed ---> <!---not in (7) get rid of unassigned reports---> 
    AND     u.user_id=#Val(auth.user_id)# 
    AND      rn.exp_date >= #Now()# 
    ORDER BY s.client_loc, rn.exp_date DESC, rn.report_name 
</cfquery> 

<cfset stores={}> 

<cfif r.recordcount> 

<cfset snum=1> 

<cfoutput query="r" group="client_loc"> 

    <!--- STORES ---> 
    <cfset stores['stores']['store[#snum#]']['storeid'] = "#storeid#"> 
    <cfset stores['stores']['store[#snum#]']['store'] = "#client_loc# - #city#, #state#"> 

    <cfset rnum=1> 
    <cfoutput> 

     <!--- REPORTS ---> 
     <cfset stores['stores']['store[#snum#]']['reports']['report[#rnum#]']['report_id'] = "#report_id#"> 
     <cfset stores['stores']['store[#snum#]']['reports']['report[#rnum#]']['report_data_id'] = "#report_data_id#"> 

      <!--- PICS ---> 
      <cfquery name="p" datasource="#this.dsn#"> 
       SELECT report_id,pic_title_id,pic_title,pic_order 
       FROM pic_titles 
       WHERE report_id = #report_id# 
       ORDER BY pic_order 
      </cfquery> 

      <cfset pnum=1> 
      <cfloop query="p"> 
       <cfset stores['stores']['store[#snum#]']['reports']['report[#rnum#]']['report_data']['pics']['pic[#pnum#]']['pic_title_id'] = "#p.pic_title_id#"> 
       <cfset stores['stores']['store[#snum#]']['reports']['report[#rnum#]']['report_data']['pics']['pic[#pnum#]']['pic_title'] = "#p.pic_title#"> 
       <cfset stores['stores']['store[#snum#]']['reports']['report[#rnum#]']['report_data']['pics']['pic[#pnum#]']['pic_order'] = "#p.pic_order#"> 
       <cfset pnum=pnum+1> 
      </cfloop> 

      <!--- QUESTIONS ---> 
      <cfquery name="q" datasource="#this.dsn#"> 
       SELECT r.report_id,r.question_id,r.question_order,v.question,v.question_stock,v.allow_comment 
       FROM vendor_questions v, report_questions_chosen r 
       WHERE v.question_id=r.question_id 
       AND r.report_id = #report_id# 
       ORDER BY r.report_id, r.question_order 
      </cfquery> 

      <cfset qnum=1> 
      <cfloop query="q"> 
       <cfset stores['stores']['store[#snum#]']['reports']['report[#rnum#]']['report_data']['questions']['q[#qnum#]']['question_id'] = "#q.question_id#"> 
       <cfset stores['stores']['store[#snum#]']['reports']['report[#rnum#]']['report_data']['questions']['q[#qnum#]']['question'] = "#q.question#"> 
       <cfset stores['stores']['store[#snum#]']['reports']['report[#rnum#]']['report_data']['questions']['q[#qnum#]']['question_order'] = "#q.question_order#"> 
       <cfset stores['stores']['store[#snum#]']['reports']['report[#rnum#]']['report_data']['questions']['q[#qnum#]']['question_stock'] = "#q.question_stock#"> 
       <cfset stores['stores']['store[#snum#]']['reports']['report[#rnum#]']['report_data']['questions']['q[#qnum#]']['allow_comment'] = "#q.allow_comment#"> 

       <cfif q.question_stock eq "Y"> 
        <!--- ANSWERS ---> 
        <cfquery name="a" datasource="#this.dsn#"> 
         SELECT a.question_id, a.answer_id, a.answer 
         FROM vendor_questions v, report_questions_chosen r, vendor_answers a 
         WHERE v.question_id=r.question_id 
         AND a.question_id = v.question_id 
         AND r.report_id = #r.report_id# 
         AND v.question_id = #q.question_id# 
         AND is_active = 1 
         ORDER BY question_id, answer_status 
        </cfquery> 

        <cfset anum=1> 
        <cfloop query="a"> 
         <cfset stores['stores']['store[#snum#]']['reports']['report[#rnum#]']['report_data']['questions']['q[#qnum#]']['answers']['a[#anum#]']['question_id'] = "#a.question_id#"> 
         <cfset stores['stores']['store[#snum#]']['reports']['report[#rnum#]']['report_data']['questions']['q[#qnum#]']['answers']['a[#anum#]']['answer_id'] = "#a.answer_id#"> 
         <cfset stores['stores']['store[#snum#]']['reports']['report[#rnum#]']['report_data']['questions']['q[#qnum#]']['answers']['a[#anum#]']['answer'] = "#a.answer#"> 
         <cfset anum=anum+1> 
        </cfloop>     

       </cfif> 

       <cfset qnum=qnum+1> 
      </cfloop> 


      <cfset rnum=rnum+1> 

    </cfoutput> 

    <cfset snum=snum+1> 
</cfoutput> 

<cfelse> 

     <cfset stores['stores']['error'] = "No reports"> 

</cfif> 


<cfset mystores = serializeJSON(stores) /> 

     <cfreturn mystores> 
    </cffunction>  

CFDUMP не выглядит плохо, но в результате JSON является неприемлемым.

CFDUMP

В противном случае JSON (частичный сниппета). Собственный JSON будет содержать массивы структур. Как создать правильный массив структур в CF или CFSCRIPT

Например, мне не нужно видеть «хранилище [3]» и «отчет [2]» в JSON, это должно быть просто массив структур с именем: пары значений.

{"stores":{"store[3]":{"reports":{"report[3]":{"report_data":{"questions":{"q[1]":{"question_stock":"N","question":"Did you complete the training... 

ЗАКЛЮЧЕНИЕ Чтобы добавить к путанице, есть несколько запросов, с несколькими петлями, чтобы раздобыть все данные, необходимые для заполнения массивов. Я не могу обвести вокруг себя голову. Спасибо за любую помощь, которую вы могли бы предоставить, чтобы указать мне в правильном направлении.

+0

Так что ждите - есть структура или массив? То есть, на верхнем уровне вам нужен список магазинов (список - это массив, не так ли?) –

+0

Магазины должны быть массивом структур, например: [{storeid: 123}] – Bobmd

+1

См. Ответ на комментарий Bernhard ниже. Я думаю, что ваша самая большая проблема не в использовании arrayAppend для добавления в ваш массив магазинов. –

ответ

1

I shouldn't have to see "store[3]" and "report[2]" in the JSON Но это ваш код! Начните с простого и попытаться понять, как это работает:

<cfset myStru = { stores = [] }> 
<cfset myTmpStru = { storeid = 101, storename = "STORE101", reports = [ ] }> 
<cfset myTmpStru2 = { reportid = 201, reportname = "REPORT201", pics = [ ] }> 
<cfset ArrayAppend(myTmpStru.reports, myTmpStru2)> 
<cfset ArrayAppend(myStru.stores, myTmpStru)> 
+0

Спасибо, Бернхард и Раймонд, сделав это на один шаг дальше, я смог получить массив PICS в JSON, и он выглядит хорошо. Мой вопрос заключается в том, как я оборачиваю результаты запроса (quies) и заполняю массивы без необходимости использовать хранилище [1], хранить [2] и т. Д. Можете ли вы предоставить быстрый пример кода, где бы вы размещали циклы & array добавляет? {"STORES": [{"STORENAME": "STORE101", "ОТЧЕТЫ": [{"REPORTNAME": "REPORT201", "PICS": [{"PICID": 301, "PICTITLE": "PIC301 "}]," REPORTID ": 201}]," STOREID ": 101}]} – Bobmd

+0

@ Поблагодарили. Очень полезно. Я сейчас экспериментирую с этим. – Bobmd

1

как I петлю вокруг результатов Кер (х годов) и заполнить массивы без использования store[1], store[2], и т.д.

на основе комментариев, несколько других советов о функции:

  1. I Тхи nk вы приближаетесь к нему назад :) Нет необходимости отслеживать позиции массива. Каждый раз, когда вы выполняете цикл, создайте новую структуру «store» («report» и т. Д.). Затем заполните тем, что при необходимости. По завершении добавьте текущий объект в соответствующий массив или структуру и забудьте об этом. Поскольку вы работаете только с одним «магазином», «отчет» и т. Д. За раз (то есть с текущим), нет необходимости беспокоиться о позициях или индексах.

    <cfset storeArray = []> 
    <cfloop ...> 
    
        <!--- create a new store object ---> 
        <cfset currStore = { "reports" = [] }> 
        ... populate .... 
    
        <cfloop ....> 
         <!--- create a new report object ---> 
         <cfset currReport = { "pics" = [], "questions" = [] }> 
         ... populate .... 
    
         <!--- add to array ---> 
         <cfset arrayAppend(currStore.reports, currReport)> 
    
        </cfloop> 
    
        <!--- add to array ---> 
        <cfset arrayAppend(storeArray, currStore)> 
    
    </cfloop> 
    
  2. Не напрямую связана с вопросом, но всегда использовать cfqueryparam.Помимо обеспечения защиты от вторжений в sql, это также помогает повысить производительность запроса, когда один и тот же оператор выполняется несколько раз, как в данном случае.

  3. Не забудьте локализовать ВСЕ функциональные локальные переменные. Это включает в себя имена запросов, переменные индекса цикла - любые переменные, используемые только внутри функции. Определение этих переменных с помощью VAR или LOCAL гарантирует, что они не просачиваются в общую область variables, что может вызвать странные и трудные способы воспроизведения ошибок при определенных условиях (просто выполните поиск по ColdFusion + race conditions).

+0

Спасибо вам всем. Ваши предложения работали как прелесть. С вашей помощью я смог заставить его работать. Я попытался подправить ваши ответы, но пока у меня не хватает репутации. – Bobmd

+0

Рад, что это помогло :) – Leigh

Смежные вопросы