ColdFusion - 如何循环通过XML输出和添加到struct或数组? [英] ColdFusion - how to loop through XML output and adding to struct or array?

查看:344
本文介绍了ColdFusion - 如何循环通过XML输出和添加到struct或数组?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想创建一个章节官员及其各自职位的列表。数据来自通过Web服务访问的一系列XML键/值对(键:Member_Name,值:Joe Member。Key:Position_Name,Value:President等)。给定章节的每个主管都有自己的Member_Name和Position_Name。

I am trying to create a list of Chapter Officers and their respective positions. The data comes from a series of XML key/value pairs accessed via web service (Key: Member_Name, Value: Joe Member. Key: Position_Name, Value: President, and so forth.) Each officer for a given chapter has their own Member_Name and Position_Name.

我正在使用的API只会返回一个整个对象,所以我设置了一个数组来转换XML名称并保存所有内容:

The API I am working with will only return an entire object, so I set up an array to convert the XML name and hold everything:

<cfset keyValue = xmlSearch(soapBody,"//*[local-name()='KeyValueOfstringanyType']") />

我的想法是循环访问该数组,对于每个关键字Member_Name和Position_Name的实例,到结构的值:

My thought was to loop through that array, and for every instance of the key Member_Name and Position_Name, add the values to a struct:

<cfset chapterOfficers=structNew()>
<cfloop index="i" from="1" to="#arrayLen(keyValue)#">
    <cfif keyValue[i].Key.xmlText EQ 'Member_Name'>
        <cfset chapterOfficers.Name=keyValue[i].Value.xmlText>
    </cfif>
    <cfif keyValue[i].Key.xmlText EQ 'Position_Name'>
        <cfset chapterOfficers.Position = keyValue[i].Value.xmlText>
    </cfif>
    <cfif keyValue[i].Key.xmlText EQ 'Term_Name'>
        <cfset chapterOfficers.Term = keyValue[i].Value.xmlText>
    </cfif>
</cfloop>

倾销这个结构给我一个漂亮的小桌子,一个人的名字,那个人的位置, term - 但只有那一个(恰好是XML文件中的最后一个条目)。甚至添加i = i + 1没有任何效果 - 几乎就像循环从结束开始,而不是继续。

Dumping this structure gives me a nice neat little table with one person's name, that person's position, and their term -- but only that one (which happens to be the last entry in the XML file). Even adding i=i+1 does not have any effect -- it's almost like the loop is starting at the end, and not continuing.

我试过其他方法向结构中添加内容, 遍历所有内容,但键/值对以不相关的顺序出现。我知道structs不是有序的,但我需要一些方法来排序从XML输出的数据。我也尝试了各种其他循环,试图添加一系列小的结构,像这样一个数组。它工作,但再次,只有那个人 - 没有实际的循环似乎发生了!我可以同时看到我需要的所有信息 - 所以也许这是为了我做错了什么?

I've tried other ways of adding things to the structure, which does loop through everything, but the key/value pairs come out in an unrelated order. I know that structs are not ordered anyways, but I need to have some way to sequence the data from the XML output. I also tried various other loops, trying to add a series of little structs like this one to an array. It worked, but again, only for that one person -- no actual "looping" seemed to take place! I can see all of the information I need, all at the same time -- so maybe it's in putting it all in order that I am doing something wrong?

谢谢所有的提前,我感谢任何建议或推动在正确的方向!

Thank you all in advance, I appreciate any suggestions or nudges in the right direction!

更新:不知道这是否有帮助,但只是现在我换了To和从循环中我使用,并设置步骤-1,它给了我的第一个人在列表中。但是还是没有循环。

UPDATE: don't know if this helps, but just now I swapped the values of To and From in the loop I am using, and set the step to -1, and it gave me the FIRST person in the list. But still did not loop.

更新:感谢Peter,这里是我正在使用的XML示例:

UPDATE: Thanks Peter, here is an example of the XML I am working with:

<b:KeyValueOfstringanyType>
                    <b:Key>Member_Guid</b:Key>
                    <b:Value i:type="d:string">006e1c09-25f9-4178-86de-13c3e63200ce</b:Value>
                 </b:KeyValueOfstringanyType>
                 <b:KeyValueOfstringanyType>
                    <b:Key>Member_Type</b:Key>
                    <b:Value i:type="d:string">Entity</b:Value>
                 </b:KeyValueOfstringanyType>
                 <b:KeyValueOfstringanyType>
                    <b:Key>Member_Name</b:Key>
                    <b:Value i:type="d:string">Member, Joe</b:Value>
                 </b:KeyValueOfstringanyType>
                 <b:KeyValueOfstringanyType>
                    <b:Key>Position_Guid</b:Key>
                    <b:Value i:type="d:string">02ae1c09-5779-4891-8cd1-05cf475cf5af</b:Value>
                 </b:KeyValueOfstringanyType>
                 <b:KeyValueOfstringanyType>
                    <b:Key>Position_Type</b:Key>
                    <b:Value i:type="d:string">CommitteePosition</b:Value>
                 </b:KeyValueOfstringanyType>
                 <b:KeyValueOfstringanyType>
                    <b:Key>Position_Name</b:Key>
                    <b:Value i:type="d:string">President</b:Value>
                 </b:KeyValueOfstringanyType>
                 <b:KeyValueOfstringanyType>
                    <b:Key>Term_Guid</b:Key>
                    <b:Value i:type="d:string">044e1c09-a90b-495f-891f-afa13e653dee</b:Value>
                 </b:KeyValueOfstringanyType>
                 <b:KeyValueOfstringanyType>
                    <b:Key>Term_Type</b:Key>
                    <b:Value i:type="d:string">CommitteeTerm</b:Value>
                 </b:KeyValueOfstringanyType>
                 <b:KeyValueOfstringanyType>
                    <b:Key>Term_Name</b:Key>
                    <b:Value i:type="d:string">2011-2012</b:Value>
                 </b:KeyValueOfstringanyType>

重复每个已存档的章节官员。

Repeats for every chapter officer on file.

UPDATE:这里是我提出的代码。它做我想要的,但有更好的方法,我相信...

UPDATE: here is the code I came up. It does what I want it to do, but there are much better ways to do it, I am sure...

首先我从SOAP响应中获得结果, 向下钻取到我需要的级别,然后剥离xml特定的东西,并获取数据到一个可用的数组:

First I get the results from the SOAP response, "drill down" to the level I need, and then strip out the xml-specific stuff and get the data into a usable array:

<cfset soapBody = xmlParse(cfhttp.fileContent)>
<cfset soapBody = soapBody['s:Envelope']['s:Body'].QueryResponse.QueryResult.Objects.anyType.Fields />
<cfset keyValue = xmlSearch(soapBody,"//*[local-name()='KeyValueOfstringanyType']") />

然后

<cfset chapterOfficers=arrayNew(2)>
<cfset x=1>
<cfset y=1>

<cfloop index="i" from="1" to="#arrayLen(keyValue)#">
    <cfif keyValue[i].Key.xmlText EQ 'Member_Name'>
        <cfset memberName = keyValue[i].Value.xmlText>
        <cfset chapterOfficers[x][y]=#memberName#>
        <cfset y=y+1>
    </cfif>
    <cfif keyValue[i].Key.xmlText EQ 'Position_Name'>
        <cfset positionName = keyValue[i].Value.xmlText>
        <cfset chapterOfficers[x][y]=#positionName#>
        <cfset x=x+1>
        <cfset y=1>
    </cfif>
    <cfif keyValue[i].Key.xmlText EQ 'Member_Guid'>
        <cfset memberGuid = keyValue[i].Value.xmlText>
        <cfset chapterOfficers[x][3]=#memberGuid#>
    </cfif>
</cfloop>

我做一些其他处理,检查变量的存在等,然后输出官员及其各自职位

I do some other processing, checking for existence of variables, etc, and then output the names of the Officers and their respective positions with

<cfloop from="1" to="#arrayLen(chapterOfficers)#" index="x">
    <p>
        <cfoutput><a href="OfficerDetail.cfm?sessionGuid=<cfoutput>#URL.sessionGuid#</cfoutput>&memberGuid=<cfoutput>#chapterOfficers[x][3]#</cfoutput>">#chapterOfficers[x][1]#</a></cfoutput><br />
        <cfoutput>#chapterOfficers[x][2]#</cfoutput><br />
    </p>
</cfloop>

我可以添加Member_Guid到数组并使用它,所以网站访问者可以点击一个人的名字以查看更多详细信息(公司,电子邮件地址等)。这就是关于它!你有什么感想?

I was able to add Member_Guid to the array and use it so site visitors can click on a person's name to see further detail (company, email address, etc). And that is about it! What do you think? Again, thanks a lot for taking the time, I really appreciate it!

推荐答案

以下是我可能解决这个问题的方法:

Here's how I would probably solve this:

<cfset var ChapterOfficers = StructNew()>
<cfset var CurMemberGuid = '' />

<cfloop index="local.CurPair" array=#keyValue#>

    <cfif CurPair.Key.XmlText EQ 'Member_Guid' >
        <cfset CurMemberGuid = CurPair.Value.XmlText />
        <cfset ChapterOfficers[CurMemberGuid] = StructNew() />
    <cfelse>
        <cfset ChapterOfficers[CurMemberGuid][CurPair.Key.XmlText] = CurPair.Value.XmlText />
    </cfif>

</cfloop>

它使用您所做的现有XmlSearch,并假设 Member_Guid 始终是第一个键/值对。我使用var / local scope假定这是一个函数(它应该是),但如果不是只是删除它们。

It uses the existing XmlSearch you've done, and assumes Member_Guid is always the first key/value pair. I've used var/local scope assuming this is going inside a function (which it probably should be), but if not just remove them.

它使用structs so lookup的特定GUID很容易,但是顺序不会被保留(虽然如果必要你可以保留一个单独的数组来做那个),你不必记住哪个数组位置匹配到哪个键。

It uses structs so lookup of a particular GUID is easy, but order isn't preserved (though if necessary you could keep a separate array to do that), and you don't have to remember which array position matches to which key.

如果你想基于其他字段进行查询,你也可以将数据转换为查询,如下:

If you wanted to lookup based on other fields, you could also convert the data into a query, like so:

<cfset var ChapterOfficers = QueryNew('Member_Guid,Member_Type,Member_Name,Position_Guid,Position_Type,Position_Name,Term_Guid,Term_Type,Term_Name')>
<cfset var CurRow = 1 />

<cfloop index="local.CurPair" array=#keyValue#>

    <cfif CurPair.Key.XmlText EQ 'Member_Guid' >
        <cfset QueryAddRow(ChapterOfficers) />
    </cfif>

    <cfset QuerySetCell(ChapterOfficers,CurPair.Key.XmlText,CurPair.Value.XmlText) />

</cfloop>

这维护了订单,使得更通用的查找更容易,到HTML。

This maintains order and makes more general lookup easier, also makes it easier if your main use is outputting direct to HTML.

我已经硬编码了列键,但是你也可以做一个预循环来整理那些首先,如果他们是负责任的

I've hard-coded the column keys there, but you could also do a pre-loop to collate those first, if they are something that is liable to change.



希望这一切都有意义吗?


Hopefully this all makes sense?

这篇关于ColdFusion - 如何循环通过XML输出和添加到struct或数组?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆