Как я могу удалить пространство имен из документа XML? - PullRequest
2 голосов
/ 23 марта 2009

В моем приложении Flex я вызываю несколько веб-сервисов .NET, которые возвращают XML. Однако все эти веб-сервисы возвращают XML с пространством имен. Я не могу прочитать / проанализировать XML без ссылки на пространство имен, что означает, что мне нужно включить следующие строки кода в каждый класс, который вызывает WebService:

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

use namespace PCRWebServices;

Я хотел бы устранить необходимость в этой статической / жестко запрограммированной логике просто для чтения XML из WebService.

Есть ли способ "удалить" пространство имен из 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 ]

3 голосов
/ 27 марта 2009

Вот еще одно решение для регулярных выражений. Это удалит несколько пространств имен, а не только одно.

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

    var resultXML:XML = new XML(String(event.result).replace(nsRegEx, ""));        
}
2 голосов
/ 19 апреля 2011

Попробуйте решение ниже. Я нашел это лучше, чем заменить строку на регулярное выражение.

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

    }
2 голосов
/ 23 марта 2009

Я нашел это решение, используя 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);
}
1 голос
/ 21 июня 2013

Я испробовал несколько решений, опубликованных здесь, с минимальным успехом.
Вот что сработало для меня ...

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, которое оказало оставить префиксы в моих данных XML.

Я счел необходимым также добавить следующий блок кода, чтобы удалить все следы исходных пространств имен (запуск вышеуказанного кода приводил к странным пространствам имен "aaa" после удаления пространства имен).

myXML.setNamespace('');
for each (var node:XML in myXML.descendants()) {
    node.setNamespace('');
    for each (var attribute:XML in node.attributes()) {
        attribute.setNamespace('');
    }
}
1 голос
/ 15 марта 2011

Хотя я согласен с тем, что подходящий способ взаимодействия с XML - это обращение к нему через его пространство имен, когда вы намеренно пытаетесь перевести или преобразовать контент из XML одного пространства имен в другое (например, FXG в MXML), иногда должен опуститься и грязный и взломать XML как строку. Это ни в коем случае не самый элегантный, и если есть более правильный способ сделать это, я открыт для этого. К сожалению, из того, что я прочитал, похоже, что вы не можете удалить пространство имен по умолчанию или последнее из объекта XML.

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

1 голос
/ 02 сентября 2010

Я бы не использовал хаки, которые удаляют пространства имен из XML как строку. Это безобразный хак (и не говоря уже о неэффективном). Что вы можете сделать, чтобы избежать жесткого кодирования пространства имен в вашем коде, это спросить у объекта xml, что это пространство имен по умолчанию, и использовать его. Как это:

var defaultNS:Namespace = xml.namespace("");  // get default namespace
use namespace defaultNS;  // use default ns
1 голос
/ 23 марта 2009

Когда вы указываете использовать пространство имен , вы устанавливаете это как пространство имен по умолчанию, вместо того, чтобы вызывать это, вы можете передать пространство имен при попытке получить доступ к элементу

var myval:String = PCRWebServices::node.@attribute;
0 голосов
/ 23 марта 2009

Я помню, что у меня были некоторые проблемы с этим. Не могу точно вспомнить, как я решил, но я предполагаю, что функция 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()

...