ColdFusion-如何遍历XML输出并添加到struct或array?

我正在尝试创建一个章节官员及其各自职位的列表.数据来自通过Web服务访问的一系列XML键/值对(键:Member_Name,值:Joe Member.键:Position_Name,值:President,依此类推.)给定章节的每个人员都有自己的Member_Name和Position_Name.

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

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

我的想法是遍历该数组,并为键Member_Name和Position_Name的每个实例将值添加到结构中:

<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>

转储此结构可以使我得到一个很好的整洁的小表,其中包含一个人的名字,该人的位置和他们的任期-但只有一个人(恰好是XML文件中的最后一个条目).即使加上i = i 1也没有任何效果-就像循环从头开始,就没有继续.

我尝试了其他将事物添加到结构的方法,该方法确实遍历了所有事物,但是键/值对却以不相关的顺序出现.我知道无论如何都没有对结构进行排序,但是我需要某种方式来排序XML输出中的数据.我还尝试了其他各种循环,试图将一系列像这样的小结构添加到数组中.它起作用了,但是同样,仅对那个人有效-似乎没有发生任何实际的“循环”!我可以同时看到所有我需要的信息-也许是为了我做错了所有事情?

预先谢谢大家,我感谢朝正确方向提出的任何建议或建议!

更新:不知道这是否有帮助,但是现在我在正在使用的循环中交换了To和From的值,并将步骤设置为-1,这使我成为列表中的第一人.但是仍然没有循环.

更新:谢谢彼得,这是我正在使用的XML的示例:

<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>

对存档中的每个章人员重复此操作.

更新:这是我提出的代码.它确实可以实现我想要的功能,但是我敢肯定,还有更好的方法…

首先,我从SOAP响应中获得结果,“向下钻取”到所需的级别,然后剥离xml特定的内容,并将数据放入可用数组中:

<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>

我进行了一些其他处理,检查是否存在变量等,然后使用以下命令输出官员的姓名及其各自的职位

<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添加到数组中并使用它,以便站点访问者可以单击某人的姓名以查看更多详细信息(公司,电子邮件地址等).就是这样!你怎么看?再次感谢您抽出宝贵的时间,我非常感谢!

最佳答案
这是我可能会解决的方法:

<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范围,假设这是在函数内部进行的(可能应该如此),但是如果不删除它们的话.

它使用结构,因此可以轻松查找特定的GUID,但是不会保留顺序(尽管如有必要,您可以保留一个单独的数组来执行此操作),并且不必记住哪个数组位置与哪个键匹配.

如果要基于其他字段进行查找,还可以将数据转换为查询,如下所示:

<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,则这将保持顺序并使得更通用的查找变得更容易.

我已经在此处对列键进行了硬编码,但是如果它们很容易更改,您也可以先进行预循环以整理它们.

希望这一切有意义吗?

转载注明原文:ColdFusion-如何遍历XML输出并添加到struct或array? - 代码日志