PDA

Просмотр полной версии : Передать ссылку на ХМЛ...


wvxvw
14.10.2006, 19:47
Вот, столкнулся с дурацкой задачей =) Нужно передать в функцию в качестве параметра ссылку на ХМЛ, думал, что если сделать так:
var my_xml:XML = new XML();
function my_fn(_xml:XML){
// изменяем что-то в ХМЛе
_xml = ...; // присваеваем тут ему какое-то новое значение
}
my_fn(my_xml);
trace(my_xml); // а вот и индейская хижина, ничего не поменялось
но если я в функции укажу прямо какой ХМЛ менять, то все работает:
var my_xml:XML = new XML();
function my_fn(_xml:XML){
// изменяем что-то в ХМЛе
_root.my_xml = ...; // присваеваем тут ему какое-то новое значение
}
my_fn(my_xml);
trace(my_xml); // трейсится как и ожидалось, с изменениями
Но второй вариант не устраивает т.как ссылку ессно нужно каждый раз другую давать...
Мож у кого есть какие соображения? Или я чего-то совсем заработался... %)

DarkLight
14.10.2006, 20:13
Ты же меняешь внутреннюю переменную функции! Сделай тип возвращаемого значения для функции хмл и его присваивай.

Это работает:
var my_xml:XML = new XML();
...
function my_fn(_xml:XML):XML {
// изменяем что-то в ХМЛе
_xml = ...
return _xml;
}
my_xml = my_fn(my_xml);
trace(my_xml);

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

wvxvw
14.10.2006, 20:42
Ну, дык фишка в том, что если передать мувик таким же образом, то все трансформации описанные в функции произойдут именно с ним... вот я и подумал, что по аналогии ХМЛ тоже так же должен себя вести...

Эта функция - конструктор класса, так что возвращать ХМЛ не получится... пока что ограничился тем, что передаю ссылку на клип содержащий итоговый ХМЛ и название переменной содержащей итоговый ХМЛ... но выглядит как-то не очень... хотелось бы более человеческий способ =(

Вот полный код, раз уж на то пошлО:
класс XMLloader
class XMLloader extends XML {
public var _path:String = "xmldata/";
public var tgt:XML;
function XMLloader(s:String, tgt:String, mc:MovieClip) {
this.ignoreWhite = true;
this.onLoad = function(ok:Boolean) {
if(ok){
mc[tgt] = splitAttr(this);
}
};
this.load(_path+s);
}
function splitAttr(_xml:XML):XML {
var _tempXML:XML = new XML();
var _fNode:XMLNode = _tempXML.createElement("f");
for (var i = 0; i<_xml.childNodes[0].childNodes.length; i++) {
var _sNode:XMLNode = _tempXML.createElement("s");
var _arr:Array = _xml.childNodes[0].childNodes[i].attributes.a.split("#");
_sNode.attributes.X = _arr[0];
_sNode.attributes.Y = _arr[1];
_sNode.attributes.NAME = _arr[2];
_sNode.attributes.DESCRIPTION = _arr[3];
_sNode.attributes.IMAGE = _arr[4];
_sNode.attributes.HOMEPAGE = _arr[5];
_fNode.appendChild(_sNode);
}
_tempXML.appendChild(_fNode);
return _tempXML;
}
}
Создание экземпляра класса
var _nxml:XML = new XML();
var _lxml:XMLloader = new XMLloader("description.xml", "_nxml", this);
var testButton:MovieClip = _root.attachMovie("move_at", "testButton", _root.getNextHighestDepth(), {_x:300, _y:300});
testButton.onRelease = function(){
trace("result "+_root._nxml.toString());
}
Так выглядит ХМЛ

<o>
<p a='50#50#ShopName#ShopDescription#shop.jpg#shp.html'/>
<p a='100#50#ShopName#ShopDescription#shop.jpg#shp.html'/>
<p a='50#100#ShopName#ShopDescription#shop.jpg#shp.html'/>
<p a='200#150#ShopName#ShopDescription#shop.jpg#shp.html'/>
</o>
Возможно есть просто другой подход?.. потому что так как-то не очень хорошо...

Хемуль
14.10.2006, 22:07
2 wvxvw:
Я думаю, как вариант, можно попробовать Function.apply...
Вроде того:

this.onLoad = function(ok:Boolean)
{
if (ok)
{
mc[tgt] = splitAttr.apply(this);
}
};

А в функции splitAttr обращаться не к _xml, а к this. Ну и параметры из функции убрать. Если вас такой вариант устроит, конечно...
Самому проверять, пройдёт ли такой вариант мне лень. ^_^ Напишите потом о результатах, пожалуйста, потому как эта тема мне тоже интересна.

wvxvw
14.10.2006, 22:54
class XMLloader extends XML {
public var _path:String = "xmldata/";
public var tgt:XML;
function XMLloader(s:String) {
this.ignoreWhite = true;
this.onLoad = function(ok:Boolean) {
if(ok){
splitAttr();
}
};
this.load(_path+s);
}
function splitAttr(){
var _tempXML:XML = new XML();
var _fNode:XMLNode = _tempXML.createElement("f");
for (var i = 0; i<this.childNodes[0].childNodes.length; i++) {
var _sNode:XMLNode = _tempXML.createElement("s");
var _arr:Array = this.childNodes[0].childNodes[i].attributes.a.split("#");
_sNode.attributes.X = _arr[0];
_sNode.attributes.Y = _arr[1];
_sNode.attributes.NAME = _arr[2];
_sNode.attributes.DESCRIPTION = _arr[3];
_sNode.attributes.IMAGE = _arr[4];
_sNode.attributes.HOMEPAGE = _arr[5];
_fNode.appendChild(_sNode);
}
_tempXML.appendChild(_fNode);
this.parseXML(_tempXML.toString());
}
}

mc._lxml = new XMLloader("description.xml");
Ну не скажу, что стало так уж прямо чудесно, но все таки поприятнее =)
В принципе проблема решилась, но если будут какие-нибудь интересные идеи - с удовольствием почитаю =)

lowka
14.10.2006, 23:47
var rebuildXML:Function = function(xml:XML):XML {
var nodeToAdd:XMLNode = xml.createElement("newnode");
var child:XMLNode = xml.firstChild;
child.attributes["a"]=99;
xml.appendChild(nodeToAdd);

return xml;
}

var xml:XML = new XML()
var textnode:XMLNode = xml.createElement("textnode");
textnode.attributes["a"]=0;
xml.appendChild(textnode);
trace(xml); //<textnode a="0" />

var newxml:XML = rebuildXML(xml);
trace(newxml);//<textnode a="99" /><newnode />

у меня почемуто все работает...

wvxvw
15.10.2006, 00:16
2 lowka:
Дык =) так-то понятно =) но это совсем не ответ на вопрос =) Вопрос был в том, как передать ссылку на ХМЛ вместо того, чтобы передавать его значение.
Т.е. лучше на примере с обжектом понятно:
var obj:Object = {};
function my_fn(){
trace(typeof(arguments[0])+" "+arguments[0].A+" "+arguments[0].B);
arguments[0].A = arguments[0].B;
trace(obj.A+" "+obj.B);
}
obj = {A:1, B:2};
my_fn(obj); //object 1 2 // 2 2 // свойство переопределилось у объекта, на который была ссылка
my_fn({A:obj.A, B:obj.B}); //object 1 2 // 1 2 // свойство, ессна не переопределилось, потому что было передано значение, а не ссылка
Так вот с ХМЛем получается именно второй случай. Т.е. в первом случае передается ссылка на объект, а во втором - его содержание. Мне нужно было именно передать ссылку, а не содержание.