Информация о происхождении экземпляра QName

Flex cookbook entry: How to know QName instance origins.

В ActionScript 3 у простого типа QName есть возможность хранить информацию о происхождении экземпляра, т.е. можно узнать, это имя атрибута или узла/свойства. Но я не смог найти простого и прямого способа «выдернуть» эту информацию из экземпляра QName. Поэтому дальше горожу свой огород. :)

В классе flash.utils.Proxy есть метод flash_proxy::isAttribute, который возвращает булево значение – имя атрибута передано или нет. Я воспользовался этим методом немного не по назначению и появился метод QNameUtils.isAttribute:

  1. package aw.utils{
  2. import flash.utils.Proxy;
  3. import flash.utils.flash_proxy;
  4.  
  5. public class QNameUtils extends Object{
  6. static private const proxyIsAttributeMethod:Function = (new Proxy()).flash_proxy::isAttribute;
  7. static public function isAttribute(name:QName):Boolean{
  8. return proxyIsAttributeMethod(name);
  9. }
  10. ...
  11. }
  12. }

Далее, стало интересно, как можно влиять на это значение – простого способа, опять таки, нет. Единственный способ , это создать в XML атрибут с таким же именем и потом получить xml.@attribute.name() – вот это будет имя атрибута. Но появилась проблема в том, что XML атрибут не может находиться в пространстве имён NULL(это обозначает «любое пространство имён»), а экземпляр QName может ссылаться на него и при создании такого атрибута он перемещается в базовое пространство имён(с uri = “”). И опять на помощь спешит flash.utils.Proxy – при попытке запросить атрибут он сам создаёт имя атрибута без изменений пространства имён или локального имени. В общем, я опять воспользовался обходным путём.

  1. package aw.utils{
  2. import flash.utils.Proxy;
  3. import flash.utils.flash_proxy;
  4.  
  5. public class QNameUtils extends Object{
  6. ...
  7. static private var _converter:ConverterProxy;
  8. static public function setAttribute(name:QName, isAttribute:Boolean=true):QName{
  9. if(isAttribute){
  10. if(!_converter) _converter = new ConverterProxy();
  11. _converter.@[name];
  12. name = _converter.getLastUsedName();
  13. }else name = new QName(name.uri, name.localName);
  14. return name;
  15. }
  16. ...
  17. }
  18. }
  19.  
  20. import flash.utils.Proxy;
  21. import flash.utils.flash_proxy;
  22.  
  23. class ConverterProxy extends Proxy{
  24. private var _lastName:QName;
  25. public function ConverterProxy():void{
  26. super();
  27. }
  28. public function getLastUsedName():QName{
  29. return this._lastName;
  30. }
  31. override flash_proxy function getProperty(name:*):*{
  32. this._lastName = name;
  33. return null;
  34. }
  35. }

Создал скрытого наследника flash.utils.Proxy исключительно для целей конвертации и использую его в методе QNameUtils.setAttribute.

В общем, встречайте aw.utils.QNameUtils, класс для работы со скрытым ключом атрибута в экземплярах QName.

Вот небольшой пример его работы:

  1. import aw.utils.QNameUtils;
  2.  
  3. var name:QName;
  4. var xml:XML = <node attr="value"/>;
  5.  
  6. name = xml.@attr.name(); // получаем имя атрибута
  7. trace(QNameUtils.isAttribute(name)); // true
  8.  
  9. name = new QName('', 'attr'); // создаём обычный экземпляр QName
  10. trace(xml.@[name]); // value
  11.  
  12. name = QNameUtils.create('', 'attr', true); // создаём экземпляр QName для атрибута
  13. trace(xml[name]); // value

Как видите, нет необходимости хранить информацию о происхождении отдельно или указывать при запросе – можно в один способ запросить узел и атрибут по динамическому имени без дополнительных хранилищ данных, ведь всё хранится прямо в экземпляре QName. А вопрос сериализации QName с ключом пусть ляжет на конкретного разработчика в конкретном случае , если кто решит воспользоваться.

Метки: , , , , , , ,

Один комментарий на «Информация о происхождении экземпляра QName»

  1. [...] атрибуты. Следует заметить, что QNameCollection игнорирует указатель атрибута в QName и если попробовать добавить атрибут, он просто [...]

Добавить комментарий

Вы должны авторизоваться для отправки комментария.