#1 Function GetMember(Arg1) doesn't work properly!

closed-out-of-date
nobody
5
2004-02-12
2003-09-02
Anonymous
No

Function GetMember(Arg1) doesn't work properly!

If my server-side method returns an array to the
client,then I cann't get what i want through the
GetMember().

I modify the xml-rpc.as file,and the modified file is
attached here.In my modified version,GetMember() does
not return any value of fundamental type,it return an
XMLRPC_object instance,we acquires the value from
this XMLRPC_object instance.

For examples:
if my server-side method returns an array!
then i can get the value as follow
result=myXMLRPC.GetResults();
myValue=result.GetMember(0).GetMember(0).GetValue();

My email:robi@greatbit.com

Discussion

  • lvxiaowei
    lvxiaowei
    2003-09-02

    Logged In: YES
    user_id=857204

    /*

    ================

    XML-RPC Flash Client, Version 0.6.1 Alpha
    Last Modified: 04-12-2001
    Copyright (C) 2001 Patrick O'Lone

    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation;
    either
    version 2.1 of the License, or (at your option) any later
    version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied
    warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR
    PURPOSE. See the
    GNU Lesser General Public License for more details.

    You should have received a copy of the GNU General Public
    License along with this program; if not, write to the Free
    Software Foundation, Inc., 59 Temple Place - Suite 330,
    Boston,
    MA 02111-1307, USA.

    Contact Information:

    Patrick O'Lone <polone@aeonsolutions.com>
    http://www.sourceforge.net/projects/xmlrpcflash/

    Isaac Levy <isaac@structuredsystems.net>
    (sourceforge admin/maintainer dot_ike)

    Contributions to this release:
    Martin Szulecki <ms@mirell.de>
    Chad Spicer <spicer@leadbased.com>

    Original contributors,
    2000-2001:
    Digital Hyakugei (Jos Yule) <jos@trapeze.com>
    (Thanks for telling me about the ignoreWhite option!)

    ==============================================
    ================ */

    // Prototypes for the XMLRPC Object

    // ADDED EVENT MODEL - Martin Szulecki
    // Supports custom onFailed, onLoaded functions and extends
    the XML Status Error Reporting
    XMLRPC.prototype.onFailed = function () {};
    XMLRPC.prototype.onLoaded = function () {};
    XMLRPC.prototype.Loaded = _OnLoaded;
    XML.prototype.ERRORCODE = new Array();
    XML.prototype.ERRORCODE[0] = "Read ok but file was
    possibly not found.";
    XML.prototype.ERRORCODE[-1] = "Unknown Error
    Code.";
    XML.prototype.ERRORCODE[-2] = "A CDATA-Range was
    not closed correctly.";
    XML.prototype.ERRORCODE[-3] = "The XML-Declaration
    was not closed correctly.";
    XML.prototype.ERRORCODE[-4] = "The DOCTYPE-
    Declaration was not closed correctly.";
    XML.prototype.ERRORCODE[-5] = "A Comment was not
    closed correctly.";
    XML.prototype.ERRORCODE[-6] = "A XML-Element was
    not valid.";
    XML.prototype.ERRORCODE[-7] = "Out of Memory.";
    XML.prototype.ERRORCODE[-8] = "An Attributevalue
    was not closed correctly.";
    XML.prototype.ERRORCODE[-9] = "No starting Tag
    found for an ending Tag.";
    XML.prototype.ERRORCODE[-10] = "No ending Tag found
    for an starting Tag.";

    // SUPPORTED METHODS (0.5 Alpha+ Supported)

    XMLRPC.prototype.AddParameter = AddParameter;
    XMLRPC.prototype.Call = Call;
    XMLRPC.prototype.IsLoaded = IsLoaded;
    XMLRPC.prototype.Parse = Parse;
    XMLRPC.prototype.GetResults = GetResults;
    XMLRPC.prototype.CreateNode = CreateNode;
    XMLRPC.prototype.HasTimedOut = HasTimedOut;

    // DEPRECATED METHODS (backwards compatible with 0.1)

    XMLRPC.prototype.CallMethod = Call;
    XMLRPC.prototype.GetFault = GetResults;

    // Prototypes for XMLRPC_Objects
    // SUPPORTED METHODS (0.5 Alpha+ Supported)

    XMLRPC_Object.prototype.AddMember = AddMember;
    XMLRPC_Object.prototype.SetValue = SetValue;
    XMLRPC_Object.prototype.GetValue = GetValue;
    XMLRPC_Object.prototype.GetMember = GetMember;

    /* ------------------------------------------------------

    METHOD: XMLRPC()
    DESCRIPTION: This method creates the XML-RPC parser
    that will be used to communicate with
    the server.
    PRECONDS: The URL of the server process must be
    known. In some cases, it maybe better
    to centralize the "Server" variable by
    hardcoding the URL. To do so, remove
    the "Server" parameter and set the
    this.Server = "/url/path".
    POSTCONDS: The XMLRPC object is initialized

    ------------------------------------------------------ */

    function XMLRPC (Server,Timeout)

    {
    this.methodCall = new XML();
    this.methodResponse = new XML();
    this.methodResponse.ignoreWhite = true;
    this.methodResponse.ref = this;

    this.Parameters = new Array();
    this.Result = null;

    // An example server might be:
    // http://www.example.com:8080/RPC2

    this.Server = Server;

    this.TransTTS = null;
    this.TransTTL = Timeout;

    trace("XMLRPC(): XMLRPC object created.");
    }

    /* ------------------------------------------------------

    METHOD: AddParameter()
    DESCRIPTION: This method adds a parameter to the
    Parameters[] array. As of 0.5 Alpha, the
    method only demands the variable. The
    CreateNode() method actually determines
    what type each variable should be.
    PRECONDS: Only one constaint - if the variable that
    is passed *is* and object, it must have
    at least one attribute - type.
    POSTCONDS: A new parameter is added to the list of
    parameters to send to RPC server.

    ------------------------------------------------------ */

    function AddParameter( arg1, arg2 )
    {
    // 0.1 Alpha method - aggregate the correct values by
    // converting to an object.

    if (arg2 != null) {

    trace("AddParameter(): Deprecated Call: Correcting...");
    arg1 = { type: arg1, value: arg2 };

    }

    // 0.5 Alpha handlers - if it is defined for us,
    // take it as is. If not, CreateNode() will make
    // an intelligent choice about the supposed type.

    if (typeof(arg1) == "object") {
    trace("AddParameter(): adding an object");
    if (arg1.type == null) {
    return false;
    }

    this.Parameters.push(arg1);
    return true;
    }

    trace("AddParameter(): adding unknown type with
    value: "+arg1);
    this.Parameters.push(arg1);
    return true;
    }

    /* ------------------------------------------------------

    METHOD: Call() or CallMethod()
    DESCRIPTION: This method creates and sends the XML-RPC
    compliant message to the RPC server.
    PRECONDS: None; you must specify a method that will
    be called upon on behalf of the server,
    though.
    POSTCONDS: The message is created, sent, and the
    method will return true.

    ------------------------------------------------------ */

    function Call ( Method )
    {
    var ParentNode, ChildNode;

    this.methodCall = new XML();
    this.methodCall.xmlDecl = "<?xml version=\"1.0\"?>";
    this.Result = null;
    // Create the <methodCall>...</methodCall> root node

    ParentNode = this.methodCall.createElement("methodCall");
    this.methodCall.appendChild(ParentNode);

    // Create the <methodName>...</methodName> node

    ChildNode = this.methodCall.createElement("methodName");
    ChildNode.appendChild(this.methodCall.createTextNode
    (Method));
    ParentNode.appendChild(ChildNode);

    // Create the <params>...</params> node

    ChildNode = this.methodCall.createElement("params");
    ParentNode.appendChild(ChildNode);
    ParentNode = ChildNode;

    // Build each <param>. Note that a recursive method,
    // CreateNode() is used to build the nodes. This is
    // necessary because the spec allows for recursive
    // complex data structures (i.e. struct in a struct).
    // If you need to verify that this document is indeed
    // generating valid XML-RPC spec documents, allow
    // for trace() statements to be generated in your
    // Flash file.

    trace("Call(): Creating the params node.");
    for (var i in this.Parameters)
    {
    ChildNode = this.methodCall.createElement("param");
    ChildNode.appendChild(this.CreateNode(this.Parameters
    [i]));
    ParentNode.appendChild(ChildNode);
    }

    trace("Call(): Resulting XML document:");
    trace("Call(): "+this.methodCall.toString());

    // Make the call. Flash uses POST method for
    // the sendAndLoad() XML methods.
    this.methodResponse.onLoad = this.Loaded;
    // Added methodCall.contentType- Isaac Levy
    // Content-Type http header value 'text/xml' now carried in
    Call headers
    this.methodCall.contentType = "text/xml";
    this.methodCall.sendAndLoad
    (this.Server,this.methodResponse);
    this.TransTTS = new Date();
    return true;
    }

    /* ------------------------------------------------------

    METHOD: CreateNode()
    DESCRIPTION: This method creates <value>...</value>
    tag pairs with the correct data types for
    each value. This method is recursively
    called for each <struct> and <array> that
    is defined.
    PRECONDS: At least one valid parameter must be
    passed to the method.
    POSTCONDS: A node representing the entire <params>
    tree is created and returned.

    ------------------------------------------------------ */

    function CreateNode ( Parameter )
    {
    var Node = this.methodCall.createElement("value");
    var TypeNode;

    // Assuming parameter is explicitly defined

    if (typeof(Parameter) == "object") {

    // Handle Explicit Simple Objects

    if ((Parameter.type == "base64") ||
    (Parameter.type == "int") ||
    (Parameter.type == "i4") ||
    (Parameter.type == "string") ||
    (Parameter.type == "double") ||
    (Parameter.type == "datetime.iso8601") ||
    (Parameter.type == "boolean")) {

    trace("CreateNode(): Creating
    object '"+Parameter.value+"' as type "+Parameter.type);
    TypeNode = this.methodCall.createElement
    (Parameter.type);
    TypeNode.appendChild(this.methodCall.createTextNode
    (Parameter.value));
    Node.appendChild(TypeNode);
    return Node;
    }

    // Handle Array Objects

    if (Parameter.type == "array") {

    var DataNode;

    trace("CreateNode(): >> Begin Array");
    TypeNode = this.methodCall.createElement("array");
    DataNode = this.methodCall.createElement("data");
    for (var i in Parameter.value)
    {
    DataNode.appendChild(this.CreateNode
    (Parameter.value[i]));
    }
    TypeNode.appendChild(DataNode);
    trace("CreateNode(): << End Array");

    Node.appendChild(TypeNode);
    return Node;
    }

    // Handle Struct Objects

    if (Parameter.type == "struct") {

    trace("CreateNode(): >> Begin struct");
    TypeNode = this.methodCall.createElement("struct");
    for (var i in Parameter.value)
    {
    var MemberNode = this.methodCall.createElement
    ("member");
    MemberNode.appendChild
    (this.MethodCall.createElement("name"));
    MemberNode.firstChild.appendChild
    (this.methodCall.createTextNode(Parameter.value[i].name));

    // Well - maybe the Parameter is suppose to be the
    value!
    // This is especially true if it is passed as part of a
    // hash to this method, where the Parameter is an
    object,
    // but the type wasn't defined! We'll cheat and let
    the
    // guessing code fix it. It just so happens that if you
    // put an object without a type, the method will
    check
    // for this first, asking the type of the object - how
    // convient!

    if (Parameter.value[i].type == null)
    MemberNode.appendChild(this.CreateNode
    (Parameter.value[i].value));
    else
    MemberNode.appendChild(this.CreateNode
    (Parameter.value[i]));

    TypeNode.appendChild(MemberNode);
    }
    trace("CreateNode(): << End struct");

    Node.appendChild(TypeNode);
    return Node;
    }

    }

    // If we are here, then by the definition of the above
    // handler, it is because we don't what this value is.
    // Time to guess! In the first case, it might be an
    // integer or a double.

    if (!isNaN(Parameter)) {

    // If the floor() value equals the Parameter, it MUST be
    an integer
    // otherwise, it is float (decimal) and therefore is a
    double.

    if (Math.floor(Parameter) == Parameter) {

    trace("CreateNode(): Guessing object '"+Parameter+"'
    to be an integer.");
    TypeNode = this.methodCall.createElement("int");

    } else {

    trace("CreateNode(): Guessing object '"+Parameter+"'
    to be a double.");
    TypeNode = this.methodCall.createElement("double");
    }

    TypeNode.appendChild(this.methodCall.createTextNode
    (Parameter));
    Node.appendChild(TypeNode);
    return (Node);
    }

    // In the second case, it might be a string

    if (typeof(Parameter) == "string") {

    trace("CreateNode(): Guessing object '"+Parameter+"'
    should be a string.");
    TypeNode = this.methodCall.createElement("string");
    TypeNode.appendChild(this.methodCall.createTextNode
    (Parameter));
    }

    Node.appendChild(TypeNode);
    return Node;
    }

    /* ------------------------------------------------------

    METHOD: Parse()
    DESCRIPTION: This method creates <value>...</value>
    tag pairs with the correct data types for
    each value. This method is recursively
    called for each <struct> and <array> that
    is defined.
    PRECONDS: At least one valid parameter must be
    passed to the method.
    POSTCONDS: A node representing the entire <params>
    tree is created and returned.

    ------------------------------------------------------ */

    function Parse ( Node )
    {
    var Data;

    if (Node.nodeType == 3)
    {
    Data = Node.nodeValue;
    }

    if (Node.nodeType == 1)
    {
    if ((Node.nodeName == "methodResponse") ||
    (Node.nodeName == "value") ||
    (Node.nodeName == "param") ||
    (Node.nodeName == "fault") ||
    (Node.nodeName == "array")) {

    Data = this.Parse(Node.firstChild);

    }

    if ((Node.nodeName == "params") ||
    (Node.nodeName == "data")) {

    trace("Parse(): >> Begin Array");
    Data = new XMLRPC_Object("array");
    for (var i in Node.childNodes) {
    Data.AddMember(this.Parse(Node.childNodes[i]));
    trace("Parse(): adding data to
    array: "+Data.GetMember(Data.value.length-1));
    }
    trace("Parse(): << End Array");

    }

    if (Node.nodeName == "struct") {

    trace("Parse(): >> Begin Struct");
    Data = new XMLRPC_Object("struct");
    for (var i in Node.childNodes) {
    var Temp = this.Parse(Node.childNodes[i]);
    Data.AddMember(Temp.name,Temp.value);
    trace("Parse(): Adding member: "+Temp.name);
    }
    trace("Parse(): << End Stuct");

    }

    // The member tag is *special*. The returned
    // value is *always* a hash (or in Flash-speak,
    // it is always an Object).

    if (Node.nodeName == "member") {

    var Temp1;
    var Temp2;
    var Data = new Object();

    Temp1 = this.Parse(Node.firstChild);
    Temp2 = this.Parse(Node.lastChild);

    if (Temp1.name != null) {

    Data.name = Temp1.name;
    Data.value = Temp2;

    } else {

    Data.name = Temp1.name;
    Data.value = Temp2;

    }

    }

    if (Node.nodeName == "name") {

    var Data = new Object();
    Data.name = this.Parse(Node.firstChild);
    return Data;

    }

    // These are the simple object data types.
    // we just want the values returned.

    if ((Node.nodeName == "string") ||
    (Node.nodeName == "int") ||
    (Node.nodeName == "i4") ||
    (Node.nodeName == "base64") ||
    (Node.nodeName == "boolean") ||
    (Node.nodeName == "double") ||
    (Node.nodeName == "dateTime.iso8601")) {

    Data = new XMLRPC_Object(Node.nodeName);
    Data.SetValue(this.Parse(Node.firstChild));
    }

    }

    return Data;
    }

    /* ------------------------------------------------------

    METHOD: IsLoaded()
    DESCRIPTION: This method creates <value>...</value>
    tag pairs with the correct data types for
    each value. This method is recursively
    called for each <struct> and <array> that
    is defined.
    PRECONDS: At least one valid parameter must be
    passed to the method.
    POSTCONDS: A node representing the entire <params>
    tree is created and returned.

    ------------------------------------------------------ */

    function IsLoaded()
    {
    //trace("IsLoaded(): Response
    loaded: "+this.methodResponse.loaded);
    return this.methodResponse.loaded;
    }

    function HasTimedOut()
    {
    var Now = new Date();

    //trace("Time: "+this.TransTTS.getTime());
    //trace("Now: "+Now.getTime());
    if ((this.TransTTS.getTime() + 1000 * this.TransTTL) <
    Now.getTime())
    return true;

    return false;
    }

    /* ------------------------------------------------------

    METHOD: GetResults()
    DESCRIPTION: This method takes the XML returned by the
    methodResponse XML Parser and converts it
    into Flash variables.
    PRECONDS: None really. However, without loading the
    results from the RPC server, this method
    will relentlessly give you null.
    POSTCONDS: If everything has worked up to this point,
    you will get an array of values, which
    may consist of any of the specs standard
    data types.

    ------------------------------------------------------ */

    function GetResults()
    {
    if (this.IsLoaded()) {

    if (this.methodResponse.status == 0) {

    trace("GetResults(): Ready to parse response.");

    if (this.Result == null) {
    this.Result = this.Parse
    (this.methodResponse.firstChild);
    }

    trace("GetResults(): Finished Parsing");
    return this.Result;
    }

    trace("GetResults(): Parsing
    error: "+this.methodResponse.status);
    return null;
    }

    trace("GetResults(): The methodResponse object has not
    yet loaded.");
    return null;
    }

    function XMLRPC_Object( Type )
    {
    this.type = Type;

    if ((this.Type == 'struct') ||
    (this.type == 'array')) {

    this.value = new Array();
    }
    else
    {
    this.value = null;
    }
    }

    function AddMember ( Arg1, Arg2, Arg3 )
    {
    if (this.type == 'struct') {

    var TempObject = new Object();

    TempObject.name = Arg1;
    TempObject.value = Arg2;
    TempObject.type = Arg3;

    this.value.push(TempObject);
    return true;
    }

    if (this.type == 'array') {

    this.value.push(Arg1);
    return true;
    }

    return false;
    }

    function GetMember(Arg1){
    if (this.type=='array'){
    return this.value[Arg1];
    }else if (this.type=='struct'){
    for (var i in this.value){
    if (this.value[i].name==Arg1){
    return this.value
    [i].value;
    }
    }
    }

    return null;
    }

    function SetValue ( Value )
    {
    if ((this.type == 'string') ||
    (this.type == 'boolean') ||
    (this.type == 'base64') ||
    (this.type == 'double') ||
    (this.type == 'dateTime.iso8601') ||
    (this.type == 'int') ||
    (this.type == 'i4')) {

    this.value = Value;
    return true;
    }

    return false;
    }

    function GetValue()
    {
    if ((this.type == 'string') ||
    (this.type == 'boolean') ||
    (this.type == 'base64') ||
    (this.type == 'double') ||
    (this.type == 'dateTime.iso8601') ||
    (this.type == 'int') ||
    (this.type == 'i4')) {

    return this.value;
    }
    return null;
    }

    /* ------------------------------------------------------

    METHOD: OnLoaded(success)
    DESCRIPTION: This is a private method for the response
    to call the appropriate event
    PRECONDS: See XML::onLoad Flash docs
    POSTCONDS: See XML::onLoad Flash docs

    ------------------------------------------------------ */

    function _OnLoaded (success)
    {
    if (success)
    {
    this.ref.onLoaded(this.ref.getResults());
    }
    else
    {
    this.ref.onFailed(this.ERRORCODE
    [this.status]);
    }
    }

     
  • Matt Shaw
    Matt Shaw
    2004-02-12

    • milestone: 252647 --> v0.6.1_Alpha_(ActionScript_1.0)
    • status: open --> closed-out-of-date
     
  • Matt Shaw
    Matt Shaw
    2004-02-12

    Logged In: YES
    user_id=961640

    Development on the 0.6.1 Alpha release is pretty much dead.
    An ActionScript 2.0 release will be available shortly.. you
    should look into this