views:

3260

answers:

6

In my Flex application, I call several .NET WebServices that return XML. However, these WebServices all return XML with a namespace. I cannot read/parse the XML without referencing the namespace, meaning that I have to include the following lines of code in each Class that calls a WebService:

private namespace PCRWebServices = "xxx.somename.web.services";

use namespace PCRWebServices;

I would like to eliminate the need for this static/hard-coded logic simply to read XML from a WebService.

Is there any way to "remove" the namespace from the XML, so that I can read it as a "normal" XML document?

I have a Class that I extend for every WebService call that handles results and faults:

private function faultHandler(event:FaultEvent):void
{

}

private function resultHandler(event:ResultEvent):void
{
    var resultXML:XML = new XML(event.result);
}

I would like to add some logic to the result handler to "convert" the XML. Any ideas?

This what trace(resultXML) returns:

<GetDataResult xmlns="xxx.somename.web.services">
  <DataSet>
    <Data>
      <IdNmb>15</IdNmb>
      <NameTxt>Hello</NameTxt>
    </Data>
    <Data>
      <IdNmb>16</IdNmb>
      <NameTxt>World</NameTxt>
    </Data>
    <Status>
      <Status>Success</Status>
    </Status>
    <ReturnCode>
      <ReturnCode>0</ReturnCode>
    </ReturnCode>
  </DataSet>
</GetDataResult>
A: 

When you specify use namespace you are setting that as the default namespace, instead of calling that you can pass the namespace when you try to access an element

var myval:String = PCRWebServices::node.@attribute;
John Isaacks
A: 

I remember having some problems with this. Can't remember excatly how I solved, but I'm guessing the removeNamespace function would be a good start. Maybe something like:

private function resultHandler(event:ResultEvent):void
{
    var resultXML:XML = new XML(event.result);

    for each( var ns:Namespace in resultXML.namespaceDeclarations() )
        resultXML.removeNamespace(ns);
}

I haven't tested the code at all, just from the top of my head.

You can read more here: http://help.adobe.com/en_US/AS3LCR/Flash_10.0/XML.html#removeNamespace()

Lillemanden
This removes the namespace from the namespace declaration, but it is still in the XML document, and I can't read the XML nodes without "use namespace...".
Eric Belair
You're right, apperently it doesn't work with all namesspaces (see the doc). I'll add a new solution.
Lillemanden
+1  A: 

I found this workaround, using RegEx to remove the namespaces from the XMLString.

http://brianmriley.wordpress.com/2008/03/14/remove-xml-namespaces-in-flex-or-as3/

Here is how I implemented it:

private function resultHandler(event:ResultEvent):void
{
    var resultXML:XML = 
        removeDefaultNamespaceFromXML(new XML(event.result));

    // play with your XML here
}

private function removeDefaultNamespaceFromXML(xml:XML):XML
{
    var rawXMLString:String = xml.toXMLString();

    /* Define the regex pattern to remove the default namespace from the 
        String representation of the XML result. */
    var xmlnsPattern:RegExp = 
        new RegExp("xmlns=[^\"]*\"[^\"]*\"", "gi");

    /* Replace the default namespace from the String representation of the 
        result XML with an empty string. */
    var cleanXMLString:String = rawXMLString.replace(xmlnsPattern, "");

    // Create a new XML Object from the String just created
    return new XML(cleanXMLString);
}
Eric Belair
It'll only remove one namespace...
Lillemanden
Thanks. Don't see the need for the downvote, as this answered my question about "A namespace". I'll upvote your answer anyways.
Eric Belair
+1  A: 

Here's another regex solution. It will remove multiple namespaces, not just one.

private function resultHandler(event:ResultEvent):void
{
    var nsRegEx:RegExp = new RegExp(" xmlns(?:.*?)?=\".*?\"", "gim");

    var resultXML:XML = new XML(String(event.result).replace(nsRegEx, ""));        
}
Lillemanden
A: 
function ResolveNameSpace( value:XML ):XML {
 return new XML( 
  value.toXMLString().replace( 
   /(xmlns(:\w*)?=\".*?\")/gim
   , ""     
  ).replace( 
   /\w+:/gim, 
   "" 
  )
 );
}
Alejandro M. Bernardis
A: 

I wouldn't use the hacks that remove namespaces from the xml as a string. That is a ugly hack (and not to mention inefficient). What you can do to avoid hardcoding the namespace in your code is to ask the xml object what it's default namespace is and use that. Like this:

var defaultNS:Namespace = xml.namespace("");  // get default namespace
use namespace defaultNS;  // use default ns
dalore