1

支部役員とそれぞれの役職のリストを作成しようとしています。データは、Web サービスを介してアクセスされる一連の XML キーと値のペアから取得されます (キー: Member_Name、Value: Joe Member、Key: Position_Name、Value: President など)。特定の支部の各役員には、独自の Member_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>

この構造をダンプすると、1 人の名前、その人の役職、任期を含む素敵な小さなテーブルが得られますが、その 1 つだけです (たまたま XML ファイルの最後のエントリになります)。i=i+1 を追加しても効果はありません。ループが最後から始まり、継続していないようです。

すべてをループする構造に何かを追加する他の方法を試しましたが、キーと値のペアは無関係な順序で出てきます。とにかく構造体が順序付けされていないことは知っていますが、XML 出力からデータを順序付ける何らかの方法が必要です。このような一連の小さな構造体を配列に追加しようとして、他のさまざまなループも試しました。それは機能しましたが、やはりその 1 人だけでした。実際の「ループ」は行われなかったようです。必要なすべての情報を同時に見ることができます。すべてを順番に並べると、間違ったことをしているのかもしれません。

事前に感謝します。正しい方向への提案やナッジに感謝します!

更新: これが役立つかどうかはわかりませんが、使用しているループで 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 を配列に追加し、それを使用して、サイト訪問者が個人の名前をクリックして詳細 (会社、電子メール アドレスなど) を表示できるようにしました。そしてそれはそれについてです!どう思いますか?繰り返しになりますが、お時間を割いていただき、本当にありがとうございます。

4

2 に答える 2

1

おそらくこれを解決する方法は次のとおりです。

<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 に直接出力する場合も簡単になります。

そこに列キーをハードコーディングしましたが、それらが変更される可能性がある場合は、それらを最初に照合するためにプレループを実行することもできます。


うまくいけば、これはすべて理にかなっていますか?

于 2012-07-29T16:40:42.487 に答える
0

Coldfusion 10 または Railo 4 では、Underscore.cfc ライブラリを使用して、ソリューションを大幅にクリーンアップできます。

<cfscript>
    soapBody = XmlParse(cfhttp.filecontent);
    fields = xmlSearch(soapBody,"//*[local-name()='Fields']");
    chapterOfficers = _.map(fields, function (field) {
        var officer = {};
        _.each(field.xmlChildren, function (KeyValueOfstringanyType) {
            var key = KeyValueOfstringanyType['b:Key'].xmlText;
            var value = KeyValueOfstringanyType['b:Value'].xmlText;
            officer[key] = value;
        });
        return officer;
    });
</cfscript>

<cfoutput>
<cfloop array="#chapterOfficers#" index="officer">
    <a href="OfficerDetail.cfm?sessionGuid=#URL.sessionGuid#&memberGuid=#officer.Member_Guid#">#officer.Member_Name#</a> 
    #officer.Position_Name#<br />
</cfloop>
</cfoutput>

今はもっと素敵ではありませんか?SOAP 応答がどのように見えるかは正確にはわかりませんが、xmlSearch() を微調整して、KeyValueOfstringanyType の親要素と一致させることができるはずです。また、不要な cfoutputs もすべて削除しました。また、XML ではなく JSON に切り替えることをお勧めします。解析するのはずっと簡単です。

(免責事項: Underscore.cfc ライブラリは私が作成しました)

于 2012-08-04T05:33:44.530 に答える