Возможно вы искали: 'Fight Club'

May 15 2025 19:35:48
  • Как сделать 8Gamers.Ru домашней страницей?
  • Игры
    • База данных по играх
    • Игровые новости
    • Игровая индустрия
    • Обзоры на игры
    • Прохождения игр
    • Гайды к играм
    • Превью о играх
    • Игровые тизеры
    • Игровые арты
    • Игровые обои
    • Игровые скриншоты
    • Игровые обложки
    • Игровые трейлеры
    • Игровое видео
    • Вышедшие игры
    • Ближайшие релизы игр
  • Кино и ТВ
    • База данных по кино
    • Статьи о кино
    • Постеры
    • Кадры из кино
    • Кино трейлеры
    • Сегодня в кино
    • Скоро в кино
  • Комиксы и манга
    • Манга по алфавиту
    • База данных по комиксах
    • Читать онлайн комиксы
    • Читать онлайн манга
    • База персонажей
  • Читы и коды
    • Чит-коды для PC игр
    • Чит-коды для консольных игр
    • Трейнеры
    • Коды Game Genie
  • Моддинг
    • Модификации
    • Карты к играм
    • Программы для моддинга
    • Статьи о моддинге
  • Геймдев
    • Всё о создании игр
    • Список движков
    • Утилиты в помощь игроделу
    • Конструкторы игр
    • Игровые движки
    • Библиотеки разработки
    • 3D-модели
    • Спрайты и тайлы
    • Музыка и звуки
    • Текстуры и фоны
  • Рецензии
    • Игры
    • Кино
    • Аниме
    • Комиксы
    • Мангу
    • Саундтреки
  • Саундтреки
    • Лирика
  • Файлы
    • Патчи к играм
    • Русификаторы к играм
    • Сохранения к играм
    • Субтитры к кино
  • Медиа
    • Видео
    • Фото
    • Аудио
    • Фан-арты
    • Косплей
    • Фото с виставок
    • Девушки из игр
    • Рисунки
    • Рисуем онлайн
    • Фотохостинг
  • Юмор
    • Анекдоты
    • Афоризмы
    • Истории
    • Стишки и эпиграммы
    • Тосты
    • Цитаты
  • Флеш
    • Азартные
    • Аркады
    • Бродилки
    • Гонки
    • Для девочек
    • Для мальчиков
    • Драки
    • Квесты
    • Леталки
    • Логические
    • Мультфильмы
    • Открытки
    • Приколы
    • Разное
    • Спорт
    • Стратегии
    • Стрелялки
Статистика

Статей: 87772
Просмотров: 96111483
Игры
Injustice:  Gods Among Us
Injustice: Gods Among Us
...
Dark Souls 2
Dark Souls 2
Dark Souls II - вторая часть самой хардкорной ролевой игры 2011-2012 года, с новым героем, сюжето...
Battlefield 4
Battlefield 4
Battlefield 4 - продолжение венценосного мультиплеер-ориентированного шутера от первого ли...
Кино
Steins;Gate
Steins;Gate
Любители японской анимации уже давно поняли ,что аниме сериалы могут дать порой гораздо больше пи...
Ку! Кин-дза-дза
Ку! Кин-дза-дза
Начинающий диджей Толик и всемирно известный виолончелист Владимир Чижов встречают на шумной моск...
Обзоры на игры
• Обзор Ibara [PCB/PS2] 18357
• Обзор The Walking ... 18801
• Обзор DMC: Devil M... 19879
• Обзор на игру Valk... 15877
• Обзор на игру Stars! 17764
• Обзор на Far Cry 3 17948
• Обзор на Resident ... 16024
• Обзор на Chivalry:... 17508
• Обзор на игру Kerb... 17981
• Обзор игры 007: Fr... 16619
Превью о играх
• Превью к игре Comp... 17960
• Превью о игре Mage... 14464
• Превью Incredible ... 14721
• Превью Firefall 13479
• Превью Dead Space 3 16334
• Превью о игре SimC... 14730
• Превью к игре Fuse 15442
• Превью Red Orche... 15542
• Превью Gothic 3 16343
• Превью Black & W... 17354
Главная » Статьи » Разное » Руководство по программированию на С++ с использованием libxml++

Руководство по программированию на С++ с использованием libxml++

From: Горшков Никита <wishmaster.nick@mail.ru..>
Newsgroups: email
Date: Mon, 7 Feb 2008 14:31:37 +0000 (UTC)
Subject: Руководство по программированию на С++ с использованием libxml++

Автор: Murray Cumming <murrayc@murrayc.com..>
Перевод: Горшков Никита <wishmaster.nick@mail.ru..> <ICQ: 278224209>

Готов выслушать замечания и предложения по поводу перевода.

Версия перевода от 22.02.2008г.

Адрес оригинала: http://libxmlplusplus.sourceforge.net/docs/manual/html/index.html


Вступление

Это руководство по программированию на языке С++ с использованием
библиотеки libxml (с примерами).

Содержание

libxml++
- Установка
- UTF-8 и Glib::ustring
- Компиляция и линковка

Парсеры
- Парсер DOM
- Парсер SAX
- TextReader парсер


libxml++

libxml++ это С++ API для популярного XML-парсера libxml, написанное на
С. libxml отличается высокой производительностью и соответствием
основным стандартам, но его С API очень сложный, даже для простых
проектов. libxml++ является простым С++-подобным API, позволяющим
создавать простые проекты с простым исходным кодом.

В отличие от других С++-парсеров, он не требует придерживаться
стандартных особенностей С++, таких как пространства имен,
STL-контейнеры или идентификация типа времени выполнения (runtime type
identification, прим. пер.), и не требует соответствия API-стандартам
предназначенным для Java. Поэтому libxml++ требует современного С++
компилятора подобного g++ 3.

В основном, libxml++ создавался для удовлетворения потребности в
надежном API и надежном ABI (ABI - Application Binary Interface, прим.
пер.) С++ XML-парсере, который смогли бы использовать в бинарном виде
как динамически подключаемую библиотеку к приложениям написанным на
языке С++, распределенным по разным адресным пространствам. Поэтому,
при обновлении libxml++ на более новую версию, все программы
использующие старую версию продолжают работать. libxml++ API
развивается постепенно за счет добавления нового кода в не содержащий
ошибок код API, а также из-за возможности параллельного использования
нескольких версий ABI одновременно. Это основные технологии и
принципы, на которых основан проект [12]GNOME , частью которого
является libxml++.


Установка

libxml++ содержится во многих Linux и *BSD дистрибутивах, но также
может быть установлен из исходных текстов под Linux и Windows. Для
компиляции подойдет любой современный компилятор, например g++, SUN
Forte, или MSVC++.

Для примера, установим libxml++ и его документацию на платформу
Debian, используя apt-get (также подойдет synaptic):

# apt-get install libxml++2.6-dev libxml++2.6-doc


Чтобы узнать, установили ли вы пакет libxml++ или что он должным
образом функционирует, используйте команду

pkg-config libxml++-2.6 --modversion.


Исходные тексты могут быть загружены с сайта
http://libxmlplusplus.sourceforge.net.

libxml++ поставляется под лицензией LGPL, которая разрешает
использовать его как динамически подключаемую библиотеку в открытом и
закрытом программном обеспечении. Лежащая в основе библиотека libxml
использует еще более богатую лицензию MIT.


UTF-8 и Glib::ustring

libxml++ API понимает строки в кодировке UTF-8 Unicode, которая может
поддерживать все известные языки и локали. UTF-8 был выбран, потому
что из всевозможных кодировок ему часто отдают предпочтение. UTF-8 это
мульти-байтовая кодировка, при этом, используемое значение некоторых
символов более 1 байта. Но для совместимости, строки "старого стиля"
представленные 7-ми битной кодировкой ASCII остаются без изменений при
кодировании в UTF-8, а UTF-8 строки не содержат нулевой байт, который
бы мешал оценивать число байтов. По этим причинам, вы можете
"спрятать" UTF-8 строки в объект std::string. К тому же, std::string
API может оперировать со строками на основе байтов, вместо символов.

Так как Стандарт С++ не имеет строкового класса, который бы мог
полностью оперировать с UTF-8, libxml++ использует класс Glib::ustring
из библиотеки glibmm. Glib::ustring содержит практически полностью
похожее на std::string API, но методы такие, как length() и operator[]
оперируют с целыми символами UTF-8, а не с одиночными байтами.

Возможно скрытое преобразование между std::string и Glib::ustring,
поэтому, вы везде сможете использовать std::string в любом случае
видимый через Glib::ustring в API, но только, если вы действительно не
заботитесь о различных локалях на любом другом языке, отличном от
английского. Однако, это очень маловероятно в нашем сегодняшнем
связанном мире!

glibmm также поддерживает полезный API для преобразования между
кодировками и локалями.


Компиляция и линковка

Для использования libxml++ в своем приложении, вы должны сообщить
компилятору, где искать хидеры и библиотеку libxml++. Для упрощения
процедуры сборки, libxml++ снабжена файлом pkg-config.pc. Для примера,
следующая команда включает нужные опции компилятора:

pkg-config libxml++-2.6 --cflags --libs


В том случае, если вы используете autoconf и automake, то наиболее
просто их использовать с макросом PKG_CHECK_MODULES в вашем
конфигурационном файле configure.ac. Для примера:

PKG_CHECK_MODULES(SOMEAPP, libxml++-2.6 >= 2.10.0)
AC_SUBST(SOMEAPP_CFLAGS)
AC_SUBST(SOMEAPP_LIBS)


Парсеры

Также как и дочерняя библиотека libxml, libxml++ поддерживает три
парсера, которые вам могут потребоваться - DOM, SAX и TextReader
парсер. Их особенности и принципы работы с ними будут объяснены ниже.

Все эти парсеры могут анализировать XML-документы непосредственно на
диске, строки или C++ std::istream. Не смотря на то, что libxml++ API
использует только Glib::ustring, а следовательно кодировку UTF-8,
libxml++ может разбирать документы в любых кодировках, конвертируя в
UTF-8 автоматически. Это преобразование не приводит к потерям
какой-либо информации, потому что UTF-8 распознает любые локали.

Помните, что в XML-документах, как правило, "пустое место" играет
роль, поэтому парсеры могут находить неожиданные узлы, где текст
содержит "пустоту" или перевод каретки. Парсер не может знать, нужны
ли вам эти узлы или нет, но ваше приложение может игнорировать их.


Парсер DOM

Парсер DOM анализирует весь документ полностью и сохраняет его
структуру в памяти. Доступен через

Parser::get_document(). При помощи методов Document::get_root_node() и
Node::get_children(), вы можете перемещаться по иерархии дерева XML
без ограничений, перепрыгивая назад или вперед по документу
основываясь на информации, с которой вы сталкиваетесь в данный момент.
Поэтому парсер DOM использует большее количество памяти, чем
остальные.

Вы должны использовать C++ RTTI (через dynamic_cast<>) для определения
типа узла и выполнения действий, которые возможны с данным типом узла.
В примере только Element имеет атрибуты. Здесь представлена
наследственная иерархия типов узлов:

* xmlpp::Node:
+ xmlpp::Attribute
+ xmlpp::ContentNode
o xmlpp::CdataNode
o xmlpp::CommentNode
o xmlpp::ProcessingInstructionNode
o xmlpp::TextNode
+ xmlpp::Element
+ xmlpp::EntityReference


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

Некоторые методы к тому же могут создавать новый дочерний Узел.
Используя его или один из методов Document::write_*(), вы можете
использовать libxml++ для построения нового XML-документа.

Пример

Этот пример анализирует документ, изучает его элементы и проверяет их.
Все приведенные здесь примеры содержатся в поставке исходных текстов
libxml++.

Source Code: http://libxmlplusplus.sourceforge.net/examples/dom_parser
File: main.cc


#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <libxml++/libxml++.h>

#include <iostream>

void print_indentation(unsigned int indentation)
{
for(unsigned int i = 0; i < indentation; ++i)
std::cout << " ";
}

void print_node(const xmlpp::Node* node, unsigned int indentation = 0)
{
std::cout << std::endl; //Separate nodes by an empty line.

const xmlpp::ContentNode* nodeContent = dynamic_cast<const xmlpp::ContentNode*>(node);
const xmlpp::TextNode* nodeText = dynamic_cast<const xmlpp::TextNode*>(node);
const xmlpp::CommentNode* nodeComment = dynamic_cast<const xmlpp::CommentNode*>(node);

if(nodeText && nodeText->is_white_space()) //Let's ignore the indenting - you don't always want to do this.
return;

Glib::ustring nodename = node->get_name();

if(!nodeText && !nodeComment && !nodename.empty()) //Let's not say "name: text".
{
print_indentation(indentation);
std::cout << "Node name = " << node->get_name() << std::endl;
std::cout << "Node name = " << nodename << std::endl;
}
else if(nodeText) //Let's say when it's text. - e.g. let's say what that white space is.
{
print_indentation(indentation);
std::cout << "Text Node" << std::endl;
}

//Treat the various node types differently:
if(nodeText)
{
print_indentation(indentation);
std::cout << "text = "" << nodeText->get_content() << """ << std::endl;
}
else if(nodeComment)
{
print_indentation(indentation);
std::cout << "comment = " << nodeComment->get_content() << std::endl;
}
else if(nodeContent)
{
print_indentation(indentation);
std::cout << "content = " << nodeContent->get_content() << std::endl;
}
else if(const xmlpp::Element* nodeElement = dynamic_cast<const xmlpp::Element*>(node))
{
//A normal Element node:

//line() works only for ElementNodes.
print_indentation(indentation);
std::cout << " line = " << node->get_line() << std::endl;

//Print attributes:
const xmlpp::Element::AttributeList& attributes = nodeElement->get_attributes();
for(xmlpp::Element::AttributeList::const_iterator iter = attributes.begin(); iter != attributes.end(); ++iter)
{
const xmlpp::Attribute* attribute = *iter;
print_indentation(indentation);
std::cout << " Attribute " << attribute->get_name() << " = " << attribute->get_value() << std::endl;
}

const xmlpp::Attribute* attribute = nodeElement->get_attribute("title");
if(attribute)
{
std::cout << "title found: =" << attribute->get_value() << std::endl;

}
}

if(!nodeContent)
{
//Recurse through child nodes:
xmlpp::Node::NodeList list = node->get_children();
for(xmlpp::Node::NodeList::iterator iter = list.begin(); iter != list.end(); ++iter)
{
print_node(*iter, indentation + 2); //recursive
}
}
}

int main(int argc, char* argv[])
{
Glib::ustring filepath;
if(argc > 1 )
filepath = argv[1]; //Allow the user to specify a different XML file to parse.
else
filepath = "example.xml";

try
{
xmlpp::DomParser parser;
parser.set_validate();
parser.set_substitute_entities(); //We just want the text to be resolved/unescaped automatically.
parser.parse_file(filepath);
if(parser)
{
//Walk the tree:
const xmlpp::Node* pNode = parser.get_document()->get_root_node(); //deleted by DomParser.
print_node(pNode);
}
}
catch(const std::exception& ex)
{
std::cout << "Exception caught: " << ex.what() << std::endl;
}

return 0;
}




Парсер SAX

Парсер SAX представляет каждый узел XML-документа как
последовательность. Так, когда вы обрабатываете один узел, вы можете
получить информацию обо всех предыдущих узлах, но, с другой стороны, у
вас не будет никакой информации о последующих узлах. Парсер SAX
использует меньше памяти, чем парсер DOM и подходит для пакетной
обработки документов.

При использовании метода parse_chunk()вместо parse(), вы можете
разбирать XML-документ по частям перед его общей обработкой.

Как показано в примере, вы должны получить ваш родительский класс из
SaxParser и заменить некоторые из виртуальных методов. Эти методы
"указателя" (в оригинале "handler" прим. пер.) будут вызваны, когда
документ проанализирован.


Пример

Этот пример показывает, как методы указателя вызываются во время
анализа.

Source Code: http://libxmlplusplus.sourceforge.net/examples/sax_parser
File: myparser.h



#ifndef __LIBXMLPP_EXAMPLES_MYPARSER_H
#define __LIBXMLPP_EXAMPLES_MYPARSER_H

#include <libxml++/libxml++.h>

class MySaxParser : public xmlpp::SaxParser
{
public:
MySaxParser();
virtual ~MySaxParser();

protected:
//overrides:
virtual void on_start_document();
virtual void on_end_document();
virtual void on_start_element(const Glib::ustring& name,
const AttributeList& properties);
virtual void on_end_element(const Glib::ustring& name);
virtual void on_characters(const Glib::ustring& characters);
virtual void on_comment(const Glib::ustring& text);
virtual void on_warning(const Glib::ustring& text);
virtual void on_error(const Glib::ustring& text);
virtual void on_fatal_error(const Glib::ustring& text);
};

#endif //__LIBXMLPP_EXAMPLES_MYPARSER_H



File: main.cc



#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <fstream>
#include <iostream>

#include "myparser.h"

int
main(int argc, char* argv[])
{
Glib::ustring filepath;
if(argc > 1 )
filepath = argv[1]; //Allow the user to specify a different XML file to parse.
else
filepath = "example.xml";

// Parse the entire document in one go:
try
{
MySaxParser parser;
parser.set_substitute_entities(true); //
parser.parse_file(filepath);
}
catch(const xmlpp::exception& ex)
{
std::cout << "libxml++ exception: " << ex.what() << std::endl;
}

// Demonstrate incremental parsing, sometimes useful for network connections:
{
//std::cout << "Incremental SAX Parser:" << std:endl;

std::ifstream is(filepath.c_str());
char buffer[64];

MySaxParser parser;
do {
is.read(buffer, 63);
Glib::ustring input(buffer, is.gcount());

parser.parse_chunk(input);
}
while(is);

parser.finish_chunk_parsing();
}

return 0;
}



File: myparser.cc



#include "myparser.h"

#include <iostream>

MySaxParser::MySaxParser()
: xmlpp::SaxParser()
{
}

MySaxParser::~MySaxParser()
{
}

void MySaxParser:Surprisedn_start_document()
{
std::cout << "on_start_document()" << std::endl;
}

void MySaxParser:Surprisedn_end_document()
{
std::cout << "on_end_document()" << std::endl;
}

void MySaxParser:Surprisedn_start_element(const Glib::ustring& name,
const AttributeList& attributes)
{
std::cout << "node name=" << name << std::endl;

// Print attributes:
for(xmlpp::SaxParser::AttributeList::const_iterator iter = attributes.begin(); iter != attributes.end(); ++iter)
{
std::cout << " Attribute " << iter->name << " = " << iter->value << std::endl;
}
}

void MySaxParser:Surprisedn_end_element(const Glib::ustring& name)
{
std::cout << "on_end_element()" << std::endl;
}

void MySaxParser:Surprisedn_characters(const Glib::ustring& text)
{
std::cout << "on_characters(): " << text << std::endl;
}

void MySaxParser:Surprisedn_comment(const Glib::ustring& text)
{
std::cout << "on_comment(): " << text << std::endl;
}

void MySaxParser:Surprisedn_warning(const Glib::ustring& text)
{
std::cout << "on_warning(): " << text << std::endl;
}

void MySaxParser:Surprisedn_error(const Glib::ustring& text)
{
std::cout << "on_error(): " << text << std::endl;
}

void MySaxParser:Surprisedn_fatal_error(const Glib::ustring& text)
{
std::cout << "on_fatal_error(): " << text << std::endl;
}



TextReader парсер


Подобно парсеру SAX, парсер TextReader подходит для пакетной
обработки, но вместо использования указателей на определенные части
документа, он позволяет определять тип текущей ветви, обработать ветвь
соответствующим образом и пропустить в документе столько, сколько
необходимо. Не так, как при использовании парсера DOM, вы не сможете в
XML-документе вернуться назад. С другой стороны, у вас не будет
расточительной по времени обработки ветвей, которые вам не нужны, что
наблюдается при использовании парсера SAX.

Все методы находятся в одном объекте синтаксического анализатора, но
их результат зависит от данной ситуации. Например, используйте
read()для перемещения к следующей текстовой ветви, а move_to_element()
для навигации по дочерним ветвям. Эти методы возвращают false, если
доступных узлов больше нет. Тогда используйте один из методов
get_name() и get_value() для проверки элементов и их атрибутов.

Пример

Этот пример проверяет каждый узел по очереди, а затем перемещается на
следующий.

Source Code: http://libxmlplusplus.sourceforge.net/examples/textreader
File: main.cc


#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <libxml++/libxml++.h>
#include <libxml++/parsers/textreader.h>

#include <iostream>

struct indent {
int depth_;
indent(int depth): depth_(depth) {};
};

std:Surprisedstream & operator<<(std:Surprisedstream & o, indent const & in)
{
for(int i = 0; i != in.depth_; ++i)
{
o << " ";
}
return o;
}

int
main(int argc, char* argv[])
{
try
{
xmlpp::TextReader reader("example.xml");

while(reader.read())
{
int depth = reader.get_depth();
std::cout << indent(depth) << "--- node ---" << std::endl;
std::cout << indent(depth) << "name: " << reader.get_name() << std::endl;
std::cout << indent(depth) << "depth: " << reader.get_depth() << std::endl;

if(reader.has_attributes())
{
std::cout << indent(depth) << "attributes: " << std::endl;
reader.move_to_first_attribute();
do
{
std::cout << indent(depth) << " " << reader.get_name() << ": " << reader.get_value() << std::endl;
} while(reader.move_to_next_attribute());
reader.move_to_element();
}
else
{
std::cout << indent(depth) << "no attributes" << std::endl;
}

if(reader.has_value())
std::cout << indent(depth) << "value: '" << reader.get_value() << "'" << std::endl;
else
std::cout << indent(depth) << "novalue" << std::endl;

}
}
catch(const std::exception& e)
{
std::cout << "Exception caught: " << e.what() << std::endl;
}
}
1188 Прочтений •  [Руководство по программированию на С++ с использованием libxml++] [08.05.2012] [Комментариев: 0]
Добавил: Ukraine Vova
Ссылки
HTML: 
[BB Url]: 
Похожие статьи
Название Добавил Добавлено
• Руководство по программированию на ... Ukraine Vova 08.05.2012
• Руководство по программированию на ... Ukraine Vova 08.05.2012
Ни одного комментария? Будешь первым :).
Пожалуйста, авторизуйтесь для добавления комментария.

Проект входит в сеть сайтов «8Gamers Network»

Все права сохранены. 8Gamers.NET © 2011 - 2025

Статьи
Рецензия на Pressure
Рецензия на Pressure
Чтобы обратить на себя внимание, начинающие маленькие разработчики, как правило, уходят в жанры, ...
Рецензия на Lost Chronicles of Zerzura
Рецензия на Lost Chron...
Игры, сделанные без любви и старания, похожи на воздушный шар – оболочка есть, а внутри пусто. Lo...
Рецензия на The Bridge
Рецензия на The Bridge
«Верх» и «низ» в The Bridge — понятия относительные. Прогуливаясь под аркой, можно запросто перей...
Рецензия на SimCity
Рецензия на SimCity
Когда месяц назад состоялся релиз SimCity, по Сети прокатилось цунами народного гнева – глупые ош...
Рецензия на Strategy & Tactics: World War 2
Рецензия на Strategy &...
Название Strategy & Tactics: World War II вряд ли кому-то знакомо. Зато одного взгляда на ее скри...
Рецензия на игру Scribblenauts Unlimited
Рецензия на игру Scrib...
По сложившейся традиции в информационной карточке игры мы приводим в пример несколько похожих игр...
Рецензия на игру Walking Dead: Survival Instinct, The
Рецензия на игру Walki...
Зомби и продукция-по-лицензии — которые и сами по себе не лучшие представители игровой биосферы —...
Обратная связь | RSS | Донейт | Статистика | Команда | Техническая поддержка