ColdFusion在具有空/未定义字段的数组上循环

ColdFusion在具有空/未定义字段的数组上循环,coldfusion,coldfusion-10,Coldfusion,Coldfusion 10,我正在从我们的一个供应商的API下载数据。数据是一个数组,但有些字段是空的,显示为未定义的。我可以通过循环获取大部分信息,但当我添加字段“notes”时,它会失败,错误为: “元素注释在作为表达式一部分引用的CFML结构中未定义。包含或处理的文件的特定序列为: C:\websites\Fire\Reports\xml\u parse\Crewsense\u payroll\u loop.cfm,第行: 21“ 当我查看转储时,我看到字段显示为“未定义”。我已经没有主意了。任何帮助都将不胜感激。我

我正在从我们的一个供应商的API下载数据。数据是一个数组,但有些字段是空的,显示为
未定义的
。我可以通过循环获取大部分信息,但当我添加字段“notes”时,它会失败,错误为:

“元素注释在作为表达式一部分引用的CFML结构中未定义。包含或处理的文件的特定序列为:

C:\websites\Fire\Reports\xml\u parse\Crewsense\u payroll\u loop.cfm,第行: 21“

当我查看转储时,我看到字段显示为“未定义”。我已经没有主意了。任何帮助都将不胜感激。我已经包含了完整的代码和一个指向显示数组的转储的链接

<cfhttp url="https://api.crewsense.com/v1/payroll? access_token=as;lkdfj;alskdfj;laksdfj&token_type=bearer&start=2019-01-05%2019:00:00&end=2019-01-06%2007:59:00" method="GET" resolveurl="YES" result="result">
</cfhttp>

<cfoutput>

<cfset ApiData = deserializeJSON(result.filecontent)>

<cfset API_ArrayLength = arraylen(ApiData)>

    <cfloop index="i" from="1" to=#API_ArrayLength#>    

    #i# #ApiData[i]["name"]#
        #ApiData[i]["employee_id"]#
        #ApiData[i]["start"]#
        #ApiData[i]["end"]#
        #ApiData[i]["total_hours"]#
        #ApiData[i]["work_type"]#
        #ApiData[i]["work_code"]#
        #ApiData[i]["user_id"]#
        #ApiData[i]["notes"]#  <---Fails here when added--->

        <cfset i = i+1>
    <br>
    </cfloop>   

    <cfdump var="#ApiData#">

</cfoutput>

#i##ApiData[i][“name”]#
#ApiData[i][“员工id”]#
#ApiData[i][“开始”]#
#ApiData[i][“结束”]#
#ApiData[i][“总时数”]#
#ApiData[i][“工作类型”]#
#ApiData[i][“工作代码”]#
#ApiData[i][“用户id”]#
#ApiData[i][“注释”]


当处理具有可选元素的数据结构时,您需要在尝试访问它们之前检查它们是否存在。否则,您将得到该错误。我已经添加了一个带有
if
条件的代码段,将函数用作示例

<cfhttp url="https://api.crewsense.com/v1/payroll? access_token=as;lkdfj;alskdfj;laksdfj&token_type=bearer&start=2019-01-05%2019:00:00&end=2019-01-06%2007:59:00" method="GET" resolveurl="YES" result="result">
</cfhttp>

<cfoutput>

    <cfset ApiData = deserializeJSON(result.filecontent)>

    <cfset API_ArrayLength = arraylen(ApiData)>

    <cfloop index="i" from="1" to=#API_ArrayLength#>    

    #i# #ApiData[i]["name"]#
        #ApiData[i]["employee_id"]#
        #ApiData[i]["start"]#
        #ApiData[i]["end"]#
        #ApiData[i]["total_hours"]#
        #ApiData[i]["work_type"]#
        #ApiData[i]["work_code"]#
        #ApiData[i]["user_id"]#
        <cfif structKeyExists(ApiData[i],"notes")>
            #ApiData[i]["notes"]#  <!--- Show 'notes' if it exists --->
        <cfelse>
            'notes' is not available  <!--- Do something here (or not) --->
        </cfif>

        <cfset i = i+1>
        <br>
    </cfloop>   

    <cfdump var="#ApiData#">

</cfoutput>

#i##ApiData[i][“name”]#
#ApiData[i][“员工id”]#
#ApiData[i][“开始”]#
#ApiData[i][“结束”]#
#ApiData[i][“总时数”]#
#ApiData[i][“工作类型”]#
#ApiData[i][“工作代码”]#
#ApiData[i][“用户id”]#
#ApiData[i][“注释”]
“备注”不可用


为了简化此操作,您可以将可选键添加为列表,然后也循环该列表,检查每个列表元素,而不是为每个键编写一个单独的
structKeyExists()
。您可以根据需要调整此列表,以减少将来的代码更改。第三个选项是一个结构数组,因此您可以根据需要列出可选键及其相关默认值。Yes good points@AdrianJ.Moreno。我只是想向OP展示如何在访问之前检查结构。除了MiguelFor的评论,考虑使用“数组”循环,而不是从/to来简化代码。