tags:

views:

1524

answers:

3

A web service return to my flex3 client this custom exception:

<SOAP-ENV:Fault xmlns:ro="urn:Gov2gLibrary" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:HNS="http://tempuri.org/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:v1="http://tempuri.org/"&gt;
 <faultcode>E2gError</faultcode>
 <faultstring>abc</faultstring>
 <detail>
  <HNS:ROException>
   <HNS:Messages>
    <HNS:T2gMsg>
     <HNS:ID>4545</HNS:ID>
     <HNS:Severity>abc</HNS:Severity>
     <HNS:Category>abc</HNS:Category>
     <HNS:Message1>abc</HNS:Message1>
     <HNS:Message2 />
    </HNS:T2gMsg>
    <HNS:T2gMsg>
     <HNS:ID>345344</HNS:ID>
     <HNS:Severity>abc</HNS:Severity>
     <HNS:Category>abc</HNS:Category>
     <HNS:Message1>abc</HNS:Message1>
     <HNS:Message2 />
    </HNS:T2gMsg>
   </HNS:Messages>
  </HNS:ROException>
 </detail>
</SOAP-ENV:Fault>

This is obviously a part of the FaultEvent object I get when the remote call fail, so I'm trying to access "T2gMsg" subnode values like this:

protected function onFaultEvent(e:FaultEvent):void
{
 var obj:Object = e.fault;
 var err:XMLList = obj.element.detail.children()[0].children();
 // now I have in err the "Messages" list, subnode of ROException,
 // so I should cycle to read one message at time:
 for each (var x:XML in err.children())
 {
  //?
 }

Now I can't figure out how to read ID, Severity etc values. I think something like "x.ID" should work but it's not, while x.child("ID") or x.elements("ID") return null. What can I do?

A: 

your xml uses namespaces, so you can try to access someNode.name().localName to dig deep inside, and use text() to get the value

for (var i:int = 0; i < x.length(); i++) {
    if (x[i].name().localName == "ID") trace('x["ID"]: ' + x[i].text());
}
George Profenza
sorry I don't understand, I know XML(x.children()[0]).localName().toString() -> "ID", but I want to access the ID value by name, like x.ID or x["ID"] or x.some_method("ID"), not by index.
Giorgio Gelardi
I guess there will be a bit of if/else action going on.
George Profenza
found it in livedocs, thanks anyway
Giorgio Gelardi
why don't you answer your question with the solution you found? putting it as part of the question is not an obvious place for the question (not to mention that the question remains without an accepted answer...)
abunetta
fair enough, so i did it
Giorgio Gelardi
A: 

thanks. along with the online doc and this discussion I understand how to access the namespace xml nodes.

I guess, if a prefix is not used as the below example xml, you need to assign the namespace for the uri being used.

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"&gt;
<soap:Body>
<FindJunctionResponse xmlns="http://someserver/Service/NamePath" >
<FindJunctionResult>
<OID>558</OID>
<ClassID>5</ClassID>
<Position>0</Position>
<EID>0</EID>
<XCoord>1662634.10015</XCoord>
<YCoord>71634.435475</YCoord>
<IsJunction>true</IsJunction>
<IsFlag>false</IsFlag>
</FindJunctionResult>
</FindJunctionResponse>
</soap:Body>
</soap:Envelope

So even though it's a little long, the "syntax" to access the xml nodes would be:

.::.....

           private function webServiceHandleResult(event:ResultEvent):void
                   {

                       XML.ignoreWhitespace;
                     var eXml:XML = new XML(event.message.body);
                     var eXmlList:XMLList = eXml.children();
                     var soapNS:Namespace = eXml.namespace("soap");
                     var xmlnsNS:Namespace =  new Namespace("http://someserver/Service/NamePath/")
                     var resulteXmlList:XMLList = eXml.soapNS::Body.xmlnsNS::FindJunctionResponse.xmlnsNS::FindJunctionResult;
                     for each (var myxml:XML in resulteXmlList.children())
                     {
                          //for each field, you can get the name and the value
                          trace("field: " + myxml.localName() + ": "+ myxml.valueOf());
                     }
                  //or reference each xml node by name.
               trace("OID: " = eXml.soapNS::Body.xmlnsNS::FindJunctionResponse.xmlnsNS::FindJunctionResult.xmlnsNS::OID);
trace("ClassID: " = eXml.soapNS::Body.xmlnsNS::FindJunctionResponse.xmlnsNS::FindJunctionResult.xmlnsNS::ClassID);
trace("Position: " = eXml.soapNS::Body.xmlnsNS::FindJunctionResponse.xmlnsNS::FindJunctionResult.xmlnsNS::Position);

trace("EID: " = eXml.soapNS::Body.xmlnsNS::FindJunctionResponse.xmlnsNS::FindJunctionResult.xmlnsNS::EID);

trace("XCoord: " = eXml.soapNS::Body.xmlnsNS::FindJunctionResponse.xmlnsNS::FindJunctionResult.xmlnsNS::XCoord);

trace("YCoord: " = eXml.soapNS::Body.xmlnsNS::FindJunctionResponse.xmlnsNS::FindJunctionResult.xmlnsNS::YCoord);

trace("IsJunction: " = eXml.soapNS::Body.xmlnsNS::FindJunctionResponse.xmlnsNS::FindJunctionResult.xmlnsNS::IsJunction);


trace("IsFlag: " = eXml.soapNS::Body.xmlnsNS::FindJunctionResponse.xmlnsNS::FindJunctionResult.xmlnsNS::IsFlag);

}
harley
A: 

(as suggested I'm moving here the solution I founded to close the question)

it was a matter of namespaces: livedocs explain we need to qualify nodes to access them:

var obj:Object = e.fault;
var doc:XML = obj.element.detail[0];
var err:XMLList = doc.children()[0].children(); // messages
var ns:Namespace = doc.namespace("HNS");
for each (var x:XML in err.children())
{
    trace(x.ns::ID);
    trace(x.ns::Severity);
    trace(x.ns::Category);
    trace(x.ns::Message1);
    trace(x.ns::Message2);
}
Giorgio Gelardi