如何从XML文档中删除命名空间?

时间:2009-03-23 13:43:56

标签: xml flex actionscript-3 web-services namespaces

在我的Flex应用程序中,我调用了几个返回XML的.NET WebServices。但是,这些WebServices都使用命名空间返回XML。我无法在不引用命名空间的情况下读取/解析XML,这意味着我必须在每个调用WebService的类中包含以下代码行:

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

use namespace PCRWebServices;

我希望不再需要这种静态/硬编码逻辑来简单地从WebService读取XML。

有没有办法从XML中“删除”命名空间,以便我可以将其作为“普通”XML文档阅读?

我有一个我为每个处理结果和错误的WebService调用扩展的类:

private function faultHandler(event:FaultEvent):void
{

}

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

我想在结果处理程序中添加一些逻辑来“转换”XML。有什么想法吗?

这是trace(resultXML)返回的内容:

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

8 个答案:

答案 0 :(得分:3)

这是另一个正则表达式解决方案。它将删除多个名称空间,而不仅仅是一个。

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

    var resultXML:XML = new XML(String(event.result).replace(nsRegEx, ""));        
}

答案 1 :(得分:2)

我发现这个解决方法,使用RegEx从XMLString中删除命名空间。

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

以下是我实施它的方式:

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);
}

答案 2 :(得分:2)

尝试以下解决方案。我发现它比用正则表达式替换字符串更好。

replaceDefaultNameSpace(src, new Namespace()); //no uri
replaceDefaultNameSpace(src, new Namespace("", "http://uri.com")); //with uri


private function replaceDefaultNameSpace (src:XML, ns:Namespace):void
    {
        var tempNs:Namespace = new Namespace ("temp");
        var node:XML;

        src.addNamespace(tempNs);
        src.setNamespace(tempNs);

        for each (node in src.descendants()) node.setNamespace(tempNs);

        src.addNamespace(ns);
        src.setNamespace(ns);

        for each (node in src.descendants()) node.setNamespace(ns);

        src.removeNamespace(tempNs);

        trace (src.toXMLString());

    }

答案 3 :(得分:1)

当您指定使用命名空间时,您将其设置为默认命名空间,而不是调用您可以在尝试访问元素时传递命名空间

var myval:String = PCRWebServices::node.@attribute;

答案 4 :(得分:1)

我不会使用从xml中删除名称空间的hack作为字符串。这是一个丑陋的黑客(更不用说效率低下)了。你可以做些什么来避免代码中的命名空间硬编码是要求xml对象它的默认命名空间是什么并使用它。像这样:

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

答案 5 :(得分:1)

虽然我同意与XML交互的适当方式是通过其命名空间解决它,当您有意尝试将内容从一个命名空间的XML转换或转换为另一个命名空间(例如,FXG到MXML)时,有时您必须下来和脏,并将XML作为字符串破解。这绝不是最优雅的,如果有更正确的方法,我愿意接受它。 不幸的是,根据我的阅读,看起来你无法从XML对象中删除默认或最后一个命名空间。

http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/XML.html#removeNamespace%28%29

答案 6 :(得分:1)

我尝试了一些在这里发布的解决方案,取得了微小的成功 这对我有用......

var myXML:XML = new XML(myString);
for each ( var ns:Namespace in myXML.namespaceDeclarations() ) {
    if (ns.prefix == 'my_namespace_prefix' || ns.uri == 'my_namespace_uri') {
        myXML.removeNamespace( new Namespace(ns.prefix, ns.uri) );
    }
}

您可以省略条件以删除所有名称空间。

我发现创建一个新的Namespace对象是必要的,因为如果按原样传递ns变量,它似乎被强制转换为String,它返回uri property,它具有在我的XML数据中保留前缀的效果。

我发现有必要添加下一个代码块,以删除原始命名空间的所有痕迹(运行上面的代码在删除命名空间后产生了奇怪的“aaa”命名空间)。

myXML.setNamespace('');
for each (var node:XML in myXML.descendants()) {
    node.setNamespace('');
    for each (var attribute:XML in node.attributes()) {
        attribute.setNamespace('');
    }
}

答案 7 :(得分:-1)

我记得有一些问题。不记得我是如何解决的,但我猜想removeNamespace函数会是一个好的开始。 也许是这样的:

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

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

我根本没有测试过代码,只是从我的脑海中开始。

您可以在这里阅读更多内容: http://help.adobe.com/en_US/AS3LCR/Flash_10.0/XML.html#removeNamespace()