21
ObjectXPathNavigator – Как и зачем? Андрей Майоров. BYTE-force

ObjectXPathNavigator - Как и зачем?

  • Upload
    sqalab

  • View
    374

  • Download
    1

Embed Size (px)

DESCRIPTION

Андрей Майоров, BYTE-force, Ярославль, Россия

Citation preview

Page 1: ObjectXPathNavigator - Как и зачем?

ObjectXPathNavigator – Как и зачем?

Андрей Майоров. BYTE-force

Page 2: ObjectXPathNavigator - Как и зачем?

Зачем нужен (ObjectXPathNavigator)?

• Операции над графом объектов в памяти:– Перемещение по дереву. Любой объект в

качестве корня.– Автоматически формируется дерево XML-узлов.– Выборки нужных объектов через XPath.

• Граф объектов – в XSLT.

Page 3: ObjectXPathNavigator - Как и зачем?

История

XPath Querying Over Objects with ОbjectXPathNavigator• Статья в MSDN March 2003. Steve Saxon, Dell

Computer Corporation.

JXPath• Простой интерпретатор XPath; может быть

применен к обычным графам объектов.• Позволяет выполнять XPath-запросы и получать

итераторы.

XPathObjectNavigator в Bamboo.Prevalence• Версия Java-библиотека Prevayler для .NET. • Содержит XPathObjectNavigator (аналог JXPath).

Page 4: ObjectXPathNavigator - Как и зачем?

Недостатки других решений

• Невозможность управлять формой XML– Что идет в элементы?– А что в атрибуты?– С какими именами?– А неймспейсы какие?

• Не расширяются снаружи– Как конвертировать значение в атрибут?– Специальная обработка нужного класса?

Page 5: ObjectXPathNavigator - Как и зачем?

Еще есть XmlSerializer

• Стандартней некуда.• Позволяет управлять формой.

• НО сначала преобразует все в XML, и только потом отдает его приложению.

Page 6: ObjectXPathNavigator - Как и зачем?

ObjectXPathNavigator

Page 7: ObjectXPathNavigator - Как и зачем?

Использование #1

var context = new ObjectXPathContext();var nav = context.CreateNavigator( o );

var ctx = new ObjectXPathContext( nsmgr );ctx.NamespaceManager.AddNamespace( "sdf", “…” );var nav = ctx.CreateNavigator( o );

Простейшее использование

Регистрация неймспейса

Page 8: ObjectXPathNavigator - Как и зачем?

Использование #2

ObjectXPathContext context = new ObjectXPathContext( nsmgr );

context.RegisterNodePolicy( typeof( INullableType ), typeof( NullableNodePolicy ) );

context.ConverterFactory.AddConverter( typeof( NullableDateTime ), new NullableDateTimeConverter() );

XPathNavigator nav = context.CreateNavigator( o );

Регистрация специальной политики и конвертера

Page 9: ObjectXPathNavigator - Как и зачем?

Разметка объектов

[XmlRoot( "product", Namespace=Namespaces.SDF )]public class Product{

[XmlAttribute( "id" )]public int ProductId{ get; set; }

[XmlAttribute( "name" )]public string Field1{ get; set; }

[XmlElement( "description" )]public string Description{ get; set ; }

[XmlElement( "Date", Form=XmlSchemaForm.Unqualified )][Converter( typeof( SimpleConverter ))]public DateTime Date{ get; set ; }

[XmlAnyElement]public XmlElement Xml{ get; set; }

}

Разметка атрибутами:

<sdf:productid="123" name="Red button" xmlns:sdf="...">

<sdf:description>Red button description

</sdf:description>

<Date>10.10.2006</Date>...

</sdf:product>

XML:

Page 10: ObjectXPathNavigator - Как и зачем?

ObjectXPathNavigator

• Центральный класс библиотеки.• Наследует у класса XPathNavigator.• Осуществляет движение по дереву узлов (элементов, атрибутов).• Дерево динамически создается по мере спуска по иерархии.• Умеет работать с «дочерними» навигаторами.• Узлы дерева хранятся в виде экземпляров класса Node.

Page 11: ObjectXPathNavigator - Как и зачем?

Node

• Аналогичен классу XmlNode.• «Отражает» реальный объект или связи между объектами.• Получение реального значения делается, когда это требуется *.

* Есть тонкости.

Page 12: ObjectXPathNavigator - Как и зачем?

NodePolicy

• Политика отвечает за поведение узла иерархии.• Соответствует паттерну Policy (Strategy).• Упрощает расширение.• Позволяет менять поведение узлов на ходу.

Page 13: ObjectXPathNavigator - Как и зачем?

Стандартные политики

• GenericNodePolicyПреобразует свойства обычного объекта в элементы и атрибуты.

• MemberNodePolicy Обслуживает узлы, значение которых еще не уточнялось навигатором.

• TextNodePolicy Для узлов типа «элемент», относящихся к полям с «простыми» значениями.

• ListNodePolicy Позволяет перемещаться по содержимому объектов, реализующих интерфейс IList.

Page 14: ObjectXPathNavigator - Как и зачем?

Конвертеры

• В XML некоторые части графа объектов показаны в виде простого текста.

• Конвертеры преобразуют значения полей в текст.• Можно писать новые конвертеры и регистрировать их

Некоторые стандартные конвертеры• GenericConverter – просто использует ToString().• BooleanConverter, DateTimeConverter, DoubleConverter и т.п. –

форматируют результат в тот формат, который принят для XML.• EnumConverter – преобразует значение в название.

Page 15: ObjectXPathNavigator - Как и зачем?

Прозрачные узлы?

public class Person { public string Name; public string[] Alias;

}

<Person><Name>John Smith</Name> <Alias>

<string>Johnny</string> <string>Smithy</string>

</Alias> </Person>

<person> <name>John Smith</name> <alias>Johnny</alias> <alias>Smithy</alias>

</person>

Берем класс … получим XML:

А хотелось-то получить:

Page 16: ObjectXPathNavigator - Как и зачем?

Прозрачные узлы!• Прозрачный узел – способ управления формой XML.• Навигатор не останавливается на прозрачном узле• Сделать узел прозрачным:

• Атрибут [Transparent(true)].• Метод INodePolicy.GetIsTransparent().

• Некоторые узлы делаются прозрачными для соответствия правилам класса XmlSerializer*.

* Следуем пока не всем правилам.

Page 17: ObjectXPathNavigator - Как и зачем?

Добавление своих политик

• Реализуем интерфейс INodePolicy.• Методы самоочевидны.• В классе нужен метод GetPolicy().

Регистрация политики• Атрибут NodePolicy на свойстве или классе.• Метод RegisterNodePolicy (тип объекта, тип политики).

– Тип объекта может быть интерфейсом.

• Событие NodePolicyGet.

public static new INodePolicy GetPolicy()

Page 18: ObjectXPathNavigator - Как и зачем?

INodePolicy

public interface INodePolicy{

INodePolicy GetNewPolicy( Node node );string GetName( Node node );string GetNamespace( Node node );XPathNodeType GetNodeType( Node node );string GetValue( Node node );bool GetIsTransparent( Node node );int GetAttributesCount( Node node );Node GetAttribute( Node node, int index );int FindAttribute( Node node, string name, string ns );int GetChildrenCount( Node node );Node GetChild( Node node, int index );

}

При смене объекта

Page 19: ObjectXPathNavigator - Как и зачем?

Свои конвертеры

• Реализует интерфейс IConverter.• ToString - преобразует значение объекта в текст.• ParseString в данной версии не используется.

Регистрация конвертера• Атрибут Converter на свойстве или классе.• Используя метод AddConverter.

public interface IConverter{

string ToString( object obj );object ParseString( string str );

}

Page 20: ObjectXPathNavigator - Как и зачем?

Возможные улучшения

• Полная совместимость со стандартным сериализатором.• Оптимизация чтения данных. • Обновление данных через навигатор.• Типизированные элементы и атрибуты.• Предотвращение зацикливания.• и т.д.

Page 21: ObjectXPathNavigator - Как и зачем?

Заключение

• Лицензия MIT-style.• Текущая версия на нашем сайте:

http://blogs.byte-force.com/files/12/objectxpathnavigator/default.aspx

• Free as in beer: