Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript (http://www.flasher.ru/forum/forumdisplay.php?f=5)
-   -   XML 2 Object (http://www.flasher.ru/forum/showthread.php?t=61856)

KidsKilla 13.08.2004 17:30

XML 2 Object
 
Вложений: 1
сделал я большим потом и кровью функцию:

function xml2Object(src) {
var xmlObject = {};
var xmlSrc = new XML();
xmlSrc.ignoreWhite = true;
xmlSrc.onLoad = function() {
xmlObject = parse(xmlSrc.firstChild.firstChild, xmlObject);
xmlObject._src = src;
if (xmlSrc.firstChild.nodeName != null) {
xmlObject._fcname = xmlSrc.firstChild.nodeName;
}
if (xmlSrc.firstChild.nodeValue != null) {
xmlObject._fcvalue = xmlSrc.firstChild.nodeValue;
}
if (xmlSrc.firstChild.attributes != null) {
xmlObject._fcattributes = new Array();
for (var i in xmlSrc.firstChild.attributes) {
xmlObject._fcattributes[i] = xmlSrc.firstChild.attributes[i];
//trace("!!!"+xmlObject._fcattributes[i]);
}
}
//trace(xmlSrc.firstChild.firstChild.nodeType)
};
xmlSrc.load(""+src);
return xmlObject;
}
function parse(foo, obj) {
var ind;
var nName = foo.nodeName.toLowerCase();
var nVal = foo.nodeValue.toLowerCase();
var nAttr = foo.attributes;
trace("<"+nName+">-<"+nVal+">-<"+nAttr["attr"]+">");
if (nName != null) {
if (obj[nName] != null) {
ind = obj[nName].length;
obj[nName] = obj[nName].concat({});
trace("<"+nName+">"+obj[nName].length)
} else {
ind = 0;
obj[nName] = [{}];
//trace("<"+nName+">"+obj[nName].length)
}
}
if (foo.nVal != null) {
obj[nName][ind]._value = nVal.toString();
//trace(obj[foo.nodeName][ind]._value);
}
obj[nName][ind]._attributes = [];
for (var klop in nAttr) {
obj[nName][ind]._attributes[klop] = nAttr[klop].toString();
//trace(obj[foo.nodeName][ind]._attributes[klop])
}
if (foo.firstChild != null) {
obj[nName][ind] = parse(foo.firstChild, obj[nName][ind]);
//trace("obj["+foo.nodeName+"]["+ind+"]")
}
if (foo.nextSibling != null) {
obj[nName][ind] = parse(foo.nextSibling, obj[nName][ind]);
}
return obj;
}
var folio = xml2Object("portfolio.xml");
if (folio != null) {
trace("_value = "+folio._fcattributes[df]);
}
_______________________
XML такой:

<fst df="dfgdfg">
<item attr="some kind of attribute" attr2="some kind of attribute #2">
<image attr2="It's workin, but badly..."/>
<image attr2="It's workin!!!"/>
<txt>dfbgdfg</txt>
</item>
<item attr="some kind of"><txt>1111</txt></item>
</fst>
_______________________

Но не работает - не увеличивает переменную ind.
Крови испорчено - море. помогите, плз.
исходник приаттачен.

fiot 13.08.2004 18:33

Код:

// Constructor
_global.XML_2_OBJECT = function(watchXML)
{
        this.$xml = this.$root=this.$parent=new Object();
        ASSetPropFlags(this, null, 1, 1);
        if (watchXML != undefined) {
                this._parse.apply(this, arguments);
        }
};
// load
XML_2_OBJECT.prototype.load = function()
{
        var loader = this._makeLoader(this);
        arguments[0] = this._makeURL(arguments[0]);
        loader.load.apply(loader, arguments);
};
// toString
XML_2_OBJECT.prototype.toString = function()
{
        return this.$xml.toString();
};
XML_2_OBJECT.prototype.getValue = function()
{
        return (this.$xml.firstChild.nodeType == 3 ? this.$xml.firstChild.nodeValue : undefined);
};
//return the nodeName
XML_2_OBJECT.prototype.getNodeName = function()
{
        return this.$xml.nodeName;
};
/*************************************************/
// Private
/*************************************************/
XML_2_OBJECT.prototype._parse = function(node, parent)
{
        this.$parent = parent;
        if (node instanceof XML) {
                this.$root = node;
                node = node.firstChild;
        } else {
                this.$root = this.$parent.$root;
        }
        this.$xml = node;
        this.attributes = node.attributes;
        if (node.nodeType == 1 and node.firstChild.nodeType != 3) {
                for (var childCounter = 0; childCounter<node.childNodes.length; childCounter++) {
                        var tempName = node.childNodes[childCounter].nodeName;
                        if (this[tempName] == undefined) {
                                this[tempName] = new Array();
                                this.length++
                                ASSetPropFlags(this[tempName], null, 1, 1);
                       
                       
                        }
                        this[tempName].push(new XML_2_OBJECT(node.childNodes[childCounter], this));
                }
        }
};

// reParse
XML_2_OBJECT.prototype._reParse = function()
{
        this._cleanup();
        this._parse(this.$xml, this.$parent);
};
XML_2_OBJECT.prototype._cleanup = function()
{
        for (var found in this) {
                delete (this[found]);
        }
};
// make path
XML_2_OBJECT.prototype._makeURL = function(host)
{
        if (this._online()) {
                var nocache = (random(100000)+100000);
                if (_global.sessionID != undefined) {
                        return host+"?sid="+_global.sessionID+"&nocache="+nocache;
                } else {
                        return host+"?nocache="+nocache;
                }
        } else {
                return host;
        }
};
XML_2_OBJECT.prototype._online = function()
{
        return (_root._url.subStr(0, 7) == "http://");
};
XML_2_OBJECT.prototype._makeLoader = function(target)
{
        var loader = new XML();
        loader.ignoreWhite = true;
        loader.link = target;
        loader.onLoad = function(ok)
        {
                if (ok) {
                        ASSetPropFlags(this.link, ["onLoad"], 1, 1);
                        this.link._cleanup();
                        ASSetPropFlags(this.link, ["onLoad"], 0, 1);
                        this.link._parse(this);
                        this.link.onLoad(true);
                        var header = this.link.attributes;
                        if (header.session != undefined) {
                                switch (header.session) {
                                case "timeout" :
                                case "end" :
                                        if (_global.session != undefined) {
                                                delete (_global.session);
                                                _global.onSessionEnd(header);
                                        }
                                        break;
                                default :
                                        _global.session = new Object();
                                        _global.session.id = header.session;
                                        _global.onSessionStart(header);
                                        break;
                                }
                        }
                } else {
                        this.link.onLoad(false);
                }
        };
        return loader;
};
ASSetPropFlags(XML_2_OBJECT.prototype, null, 1, 1);
//******************************
menu = new XML_2_OBJECT();
menu.load("menu_en.xml");
menu.onLoad = function(ok)
{
        if (ok) {
                _root.test();
        } else {
                trace("error");
        }
};


Nox Noctis 13.08.2004 18:44

почему вы стремитесь к сложному взамен простого?
ЗАЧЕМ?
объясните, а...

2fiot
это всё канеш круто, только я не понимаю зачем оно :))
объясните? столько работы не может быть просто так...

2KidsKilla
можешь сформулировать задачу? по-моему это какой-то код-ради-кода. байт-шлак :)

fiot 13.08.2004 18:53

Nox Noctis
очень хотелось иметь такую штуку как xml в object ...
создаёт такую штуку...
Код:

_level0.menu = [object #2, class 'XML_2_OBJECT'] {
    onLoad:[function 'onLoad'],
    attributes:[object #4] {},
    settings:[object #5, class 'Array'] [
      0:[object #6, class 'XML_2_OBJECT'] {
        attributes:[object #7] {},
        background:[object #8, class 'Array'] [
          0:[object #9, class 'XML_2_OBJECT'] {
            attributes:[object #10] {
              color:"#FF0000",
              src:"bg.jpg"
            }
          }
        ],
        length:8,
        spacing:[object #11, class 'Array'] [
          0:[object #12, class 'XML_2_OBJECT'] {
            attributes:[object #13] {
              value:"10px"
            }
          }
        ],

обрашение просто класс...
Код:

lang$ = "en";
trace(_root.menu.settings[0].background[0].attributes.color);
trace(_root.menu.items[0].item[0].attributes[lang$]);
trace(_root.menu.items[0].item.length);

ну а Вам конечно же решать ... пользоваться ей или писать свой парсер...

KidsKilla 13.08.2004 18:59

значтак:

делал я функцию для перевода xml в объект для последующего пользования.

на выходе должно получиться чето вроде:

var someVar = myObjectFromXml.tag[0].attributes["id"]

и в someVar окажется к примеру "четотам"
если в xml'е написано:

<firstTag>
<tag id="четотам" />
<tag id="четотам другое" />
</firstTag>

вооот...
можно, конечно, воспользоваться похожими но другими функциями но там на выходе как правило синтаксис хзкакой.
+хочу сам разобраться)
да и вообще раз начал...

это была предыстория. теперь по поводу моих соображений че там не то:
там не обновляется индекс (ind). значит ничего не работает. да и на выходе по-моему один выхлоп. кароче я запутался.

KidsKilla 13.08.2004 19:22

2 fiot

слу, в принципе это то самое. ток есть несколько вопросов:
1)куда он сует nodeValue => как достать.
2)что он делает с регистром
3)если не сложно, то покажи, как добраться до след. вещей:
<firstTag>
<item id="Id" />
<txt>какой-то текст</txt>
какой-то другой текст
</firstTag>
а)"какой-то другой текст"
б)"какой-то текст"
в)"Id"

вродь все...
я потому и писал свой парсер, что документации по прочим - с гулькин нос...

Nox Noctis 13.08.2004 19:44

то есть вы хотите готовую и понятную структуру ХМЛ при помощи офигенной функции перевести в такую же структуру класса Object?

в чем сверхзадача-то? :) надо сделать чтобы ко всем тегам ХМЛ можно было образаться по имени, да? не проще ли обращаться к хмлу через массивы childNodes?

ну ладно, хотите так хотите.

2fiot
идея понятна, но, имха, соотношение выделки и овчинки явно не в пользу последней :)

2KidsKilla
там бардак у тебя с рекурсией. и с тем что ты проверяешь фолио сразу после того как вызвал загрузку хмал, хотя это бредятина :)

и надо разнести загрузку и парсер.

вобщем всё переделать :)

fiot 13.08.2004 19:56

Код:

XML
<?xml version="1.0" encoding="UTF-8"?>
<firstTag>
        <txt>
                        <item type="myText" name="text_name" text="BLLAAAA"/>
        </txt>
</firstTag>

Код:


test = new XML_2_OBJECT();
test.load("me.xml")
test.onLoad = function (ok){
        ok ? t() : trace('load =(')
        }
t = function ()
{
        trace(test.txt[0].item[0].attributes.text)
}

ctrl+alt+v и смотришь иерархию
ЗЫ. первый тег игнорируется...

Nox Noctis
Цитата:

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

KidsKilla 13.08.2004 20:01

2 Nox Noctis
tanx, бум смотреть.

2 flot
пасиб, но с nodeValue то чего?
мне он ну ОООчень нужен. расписывать работы-то надо как то...

fiot 13.08.2004 20:08

Код:

XML_2_OBJECT.prototype.getValue = function()
{
return (this.$xml.firstChild.nodeType == 3 ? this.$xml.firstChild.nodeValue : undefined);
};

ну смоти же тут все напсано...
если тип ноды текс то вертуть валуе елсе не чего ...
ЗЫ. а зачем оно тебе сдесь ? у тебя ведь уже объект массив...

Nox Noctis 13.08.2004 20:10

только из любви к искусству :)
(смысла в этом всём я по-прежнему не наблюдаю...)

старался сделать близко к тому что пытался сделать ты.
Код:

//
// парсер
// выполняет обход вширину по сути, делает объекты из нод.
//
XML.prototype.parse2Object = function() {
        var obj = {};
                // свойства ноды
        obj._value = this.nodeValue;
        obj._name = this.nodeName;
        obj._attributes = {};
                //
        for (var i in this.attributes) {
                obj._attributes[i] = this.attributes[i];
        }
                //
                // перебор дочерних нод
                //
        for (var i = 0; i<this.childNodes.length; i++) {
                if (this.childNodes[i].nodeType == 1) {
                        if (!obj[this.childNodes[i].nodeName].length) {
                                obj[this.childNodes[i].nodeName] = [];
                        }
                        obj[this.childNodes[i].nodeName].push(this.childNodes[i].parse2Object());
                }
        }
        return obj;
};
XMLNode.prototype.parse2Object = XML.prototype.parse2Object;
//
// загрузчик ХМЛа отдельно от парсера
// создаёт объект xmlObject в текущей области видимости
//
xmlSrc = new XML();
xmlSrc.ignoreWhite = true;
xmlSrc.onLoad = function(flag) {
        if (flag) {
                xmlObject = this.firstChild.parse2Object();
        } else {
                trace("what the hell is going on?");
        }
};
xmlSrc.load("portfolio.xml");


Nox Noctis 13.08.2004 20:12

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

KidsKilla 13.08.2004 20:57

шпасиба Nox =)
 
ващето я хочу текстовую ноду запихнуть в св-во _value родительского тега...
во это чето не догоняю ща как замутить...

KidsKilla 13.08.2004 21:13

вот еще что...
trace(xmlObject) - говорит undefined типа парсер не записал в xmlObject ничего...

Nox Noctis 13.08.2004 21:32

а когда ты трейсишь? :)
сдаётся мне ты трейсишь это дело тогда, когда ХМЛ даже еще не загрузился, не то что не отпарсился... потому и андефайнед.

Nox Noctis 13.08.2004 21:36

исправленный вариант:
Код:

//
// парсер
// выполняет обход вширину по сути, делает объекты из нод.
//
XML.prototype.parse2Object = function() {
        var obj = {};
        // свойства ноды
        if (this.nodeValue.length) {
                obj._value = this.nodeValue.length;
        } else {
                obj._value = "";
        }
        obj._name = this.nodeName;
        obj._attributes = {};
        //
        for (var i in this.attributes) {
                obj._attributes[i] = this.attributes[i];
        }
        //
        // перебор дочерних нод
        //
        for (var i = 0; i<this.childNodes.length; i++) {
                if (this.childNodes[i].nodeType == 1) {
                        if (!obj[this.childNodes[i].nodeName].length) {
                                obj[this.childNodes[i].nodeName] = [];
                        }
                        obj[this.childNodes[i].nodeName].push(this.childNodes[i].parse2Object());
                } else if (this.childNodes[i].nodeType == 3) {
                        obj._value += this.childNodes[i].nodeValue;
                }
        }
        return obj;
};
XMLNode.prototype.parse2Object = XML.prototype.parse2Object;
//
// загрузчик ХМЛа отдельно от парсера
// создаёт объект xmlObject в текущей области видимости
//
xmlSrc = new XML();
xmlSrc.ignoreWhite = true;
xmlSrc.onLoad = function(flag) {
        if (flag) {
                xmlObject = this.firstChild.parse2Object();
        } else {
                trace("what the hell is going on?");
        }
};
xmlSrc.load("portfolio.xml");

всё нехитро как видишь :)

KidsKilla 15.08.2004 18:14

Отдельное спасибо Nox)
 
ищез на снос винды)

а штука эта всё же полезна если интересно могу объяснить чем))

KidsKilla 15.08.2004 22:00

кстати, Nox, я подобным синтаксисом не пользовался.
как передать в функцию parse2Oobject переменную?

Antares 16.08.2004 00:21

Re: Отдельное спасибо Nox)
 
Цитата:

Оригинал написал(а) KidsKilla
а штука эта всё же полезна если интересно могу объяснить чем))
Ну и? :)

KidsKilla 16.08.2004 02:32

с переменными разобрался. там другой затык)))

по поводу пользы:
эту штуку можно использовать в качестве оотправной точки для создания парсера хтмл(<sup> к примеру) это, правда, более глобальная штука)

лично мне это нужно по 2м причинам - 1)весь текст собирается в 1м св-ве 2)гораздо проще узнать сколько определенных тегов в данной ноде. да и вообще на мой взгляд проще использовать obj.item[1].tag[5] чем выискивать стандартными способами. логичнее...

fiot 16.08.2004 03:07

KidsKilla
чёго то я не понял что ты этим хотел сказать ...

Bad Habit
нужно для того что бы: преобразовывать внешний xml в структуру object.array[item].array[item].attribute.value

Antares 16.08.2004 03:57

2KidsKilla
Видимо, это дело вкуса.

2fiot
Это я понимаю. Мне маштабы практической пользы от этого стали интересны. Потому что я отчасти считаю, что Нокс прав...

KidsKilla 16.08.2004 04:29

по большей части действительно дело вкуса.
лично я с объектом XML неоч. вот и выкручиваюсь))

есть вопрос. как узнать когда парсер завершил работу?

Nox Noctis 16.08.2004 11:44

Цитата:

Оригинал написал(а) KidsKilla
есть вопрос. как узнать когда парсер завершил работу?
вся рекурсия выполняется сразу после вызова. то есть следующая за вызовм срочка скрипта выполнится только тогда когда всё уже распарсилось :)

вот сразу после
xmlObject = this.firstChild.parse2Object();

и ставь что тебе там надо...

KidsKilla 16.08.2004 15:11

Вложений: 1
да?

тогда ничерта не понимаю:

Object.prototype.makeObj = function(src ,tags) {
...
xmlSrc.onLoad = function(flag) {
if (flag) {
xmlObject = this.firstChild.parse2Object(tags);
trace(xmlObject._value)
...
}
...
}

trace выдает undefined
хотя если сделать это все вне функции(как у тебя, Nox) и проверять спустя какое то время все фурычит...


Часовой пояс GMT +4, время: 19:49.

Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.