Просмотр полной версии : XML 2 Object
KidsKilla
13.08.2004, 17:30
сделал я большим потом и кровью функцию:
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.
Крови испорчено - море. помогите, плз.
исходник приаттачен.
// 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
можешь сформулировать задачу? по-моему это какой-то код-ради-кода. байт-шлак :)
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
там бардак у тебя с рекурсией. и с тем что ты проверяешь фолио сразу после того как вызвал загрузку хмал, хотя это бредятина :)
и надо разнести загрузку и парсер.
вобщем всё переделать :)
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 то чего?
мне он ну ОООчень нужен. расписывать работы-то надо как то...
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
ващето я хочу текстовую ноду запихнуть в св-во _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
ищез на снос винды)
а штука эта всё же полезна если интересно могу объяснить чем))
KidsKilla
15.08.2004, 22:00
кстати, Nox, я подобным синтаксисом не пользовался.
как передать в функцию parse2Oobject переменную?
Оригинал написал(а) KidsKilla
а штука эта всё же полезна если интересно могу объяснить чем))
Ну и? :)
KidsKilla
16.08.2004, 02:32
с переменными разобрался. там другой затык)))
по поводу пользы:
эту штуку можно использовать в качестве оотправной точки для создания парсера хтмл(<sup> к примеру) это, правда, более глобальная штука)
лично мне это нужно по 2м причинам - 1)весь текст собирается в 1м св-ве 2)гораздо проще узнать сколько определенных тегов в данной ноде. да и вообще на мой взгляд проще использовать obj.item[1].tag[5] чем выискивать стандартными способами. логичнее...
KidsKilla
чёго то я не понял что ты этим хотел сказать ...
Bad Habit
нужно для того что бы: преобразовывать внешний xml в структуру object.array[item].array[item].attribute.value
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
да?
тогда ничерта не понимаю:
Object.prototype.makeObj = function(src ,tags) {
...
xmlSrc.onLoad = function(flag) {
if (flag) {
xmlObject = this.firstChild.parse2Object(tags);
trace(xmlObject._value)
...
}
...
}
trace выдает undefined
хотя если сделать это все вне функции(как у тебя, Nox) и проверять спустя какое то время все фурычит...
Работает на vBulletin ® версия 3.7.3. Copyright ©2000-2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Copyright © 1999-2008 Flasher.ru. All rights reserved.