Читайте также: |
|
Для начала создадим 3 переменных типа xmlChar:
xmlChar *uri;//используется для хранения аттрибутов
xmlChar *color;//используется для хранения значения цвета
xmlChar *font;//используется для хранения значения шрифта
Загрузка данных из XML файла происходит в функции loadHighlightingData():
void loadHighlightingData()
{
xmlDocPtr doc1;
const char * filename = "config.xml";
doc1 = xmlReadFile(filename, NULL, XML_PARSE_NONET);
if(is_valid(doc1, "schema.xsd") == 1)
{
int i = 0;
xmlDocPtr xmldoc = NULL;
xmlChar *uri;
if((xmldoc = xmlReadFile(filename, NULL, 0)) == NULL) return;
xmlNodePtr cur = xmlDocGetRootElement(xmldoc);
parseXMLDoc(xmldoc, "style", "entry");
parseXMLDoc(xmldoc, "keywords", "keyword");
parseXMLDoc(xmldoc, "types", "type");
xmlFree(uri);
xmlFree(color);
xmlFree(font);
}else
{
//Ошибка в XML
xmlErrorPtr XMLError;
XMLError = xmlGetLastError();
fl_alert(XMLError->message);
}
}
Сначала мы создаём указатель на XML документ командой xmlDocPtr doc1;, присваиваем имя загружаемого файла переменной filename. Затем считываем файл и проверяем его при помощи XML Schema. Проверку осуществляет функция is_valid (const xmlDocPtr doc, const char *schema_filename), получающая в качестве аргументов указатель на XML документ и имя файла XML Schema. В данной функции сначала загружается файл схемы:
xmlDocPtr schema_doc = xmlReadFile(schema_filename, NULL, XML_PARSE_NONET);
if (schema_doc == NULL) {
fl_alert("The schema cannot be loaded or is not well-formed");
return -1;
}
В случае невозможности загрузить файл выводится соответствующее сообщение при помощи функции fl_alert();
Далее создаётся указательна контекст парсера схемы, и также выводится сообщение о ошибке при невозможности его создания:
xmlSchemaParserCtxtPtr parser_ctxt = xmlSchemaNewDocParserCtxt(schema_doc);
if (parser_ctxt == NULL) {
fl_alert("Unable to create a parser context for the schema", "Ok");
xmlFreeDoc(schema_doc);
return -2;
}
Затем сама схема проверяется на корректность и также выдаётся сообщение о ошибке при нахождении ошибок в схеме:
xmlSchemaPtr schema = xmlSchemaParse(parser_ctxt);
if (schema == NULL) {
fl_alert("the schema itself is not valid", "Ok");
xmlSchemaFreeParserCtxt(parser_ctxt);
xmlFreeDoc(schema_doc);
return -3;
}
После этого создаётся контекст проверки:
xmlSchemaValidCtxtPtr valid_ctxt = xmlSchemaNewValidCtxt(schema);
if (valid_ctxt == NULL) {
fl_alert("unable to create a validation context for the schema", "Ok");
xmlSchemaFree(schema);
xmlSchemaFreeParserCtxt(parser_ctxt);
xmlFreeDoc(schema_doc);
return -4;
}
И наконец, происходит проверка XML документа:
int is_valid = (xmlSchemaValidateDoc(valid_ctxt, doc) == 0);
xmlSchemaFreeValidCtxt(valid_ctxt);
xmlSchemaFree(schema);
xmlSchemaFreeParserCtxt(parser_ctxt);
xmlFreeDoc(schema_doc);
return is_valid? 1: 0;
В случае, если загружаемый XML документ имеет ошибки, то выполняется следующий код:
xmlErrorPtr XMLError;
XMLError = xmlGetLastError();
fl_alert(XMLError->message);
Здесь мы создаём указатель указатель на структуру XMLError, заносим в эту структуру сведения о последней ошибке, и затем выдаём сообщение о ошибке при помощи функции fl_allert();.
Если проверка XML файла прошла успешно, то выполняется следующий код:
xmlDocPtr xmldoc = NULL;
if((xmldoc = xmlReadFile(filename, NULL, 0)) == NULL) return;
xmlNodePtr cur = xmlDocGetRootElement(xmldoc);
parseXMLDoc(xmldoc, "style", "entry");
parseXMLDoc(xmldoc, "keywords", "keyword");
parseXMLDoc(xmldoc, "types", "type");
xmlFree(uri);
xmlFree(color);
xmlFree(font);
Здесь мы создаём указатель на XML документ, загружаем его из файла, получаем указатель на корневой элемент документа и заполняем таблицу стилей данными из XML документа при помощи функции parseXMLDoc(xmlDocPtr doc, char *nodeName, char *curNode). Эта функция вызывается 3 раза: для чтения данных подсветки, для получения списка ключевых слов и списка типов. Рассмотрим эту функцию подробнее:
void parseXMLDoc(xmlDocPtr doc, char *nodeName, char *curNode)
{
xmlNodePtr cur;
cur = xmlDocGetRootElement(doc);
cur = cur->xmlChildrenNode;
while (cur!= NULL)
{
if ((!xmlStrcmp(cur->name, (const xmlChar *) nodeName)))
{
parseNodes(doc, cur, curNode);
}
cur = cur->next;
}
}
Сначала создаётся указатель на элемент документа и ему присвается значение корневого элемента. Затем устанавливается режим дочерних элементов и в цикле осуществляется поиск элемента, заданного вторым параметром функции. При его нахождении выполняется функция parseNodes(xmlDocPtr doc, xmlNodePtr cur, char *curNode), которая и производит загрузку значений в таблицы стилей, ключевых слов и типов. Данная функция реализована следующим образом:
void parseNodes(xmlDocPtr doc, xmlNodePtr cur, char *curNode)
{
xmlChar *key;
int exit(0);
cur = cur->xmlChildrenNode;
while(cur!= NULL)
{
if((!xmlStrcmp(cur->name, (const xmlChar *) curNode)))
{
if((!xmlStrcmp(cur->name, (const xmlChar *) "entry")))
{
parseStyles(doc, cur, "Plain");
parseStyles(doc, cur, "Line Comments");
parseStyles(doc, cur, "Block Comments");
parseStyles(doc, cur, "Strings");
parseStyles(doc, cur, "Directives");
parseStyles(doc, cur, "Types");
parseStyles(doc, cur, "Keywords");
return;
}else
{
key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
if(strcmp(curNode, "type") == 0)
{
code_types.push_back((const char *) key);
}else
{
code_keywords.push_back((const char *) key);
}
xmlFree(key);
}
}
cur = cur->next;
}
return;
}
Данная функция состоит из 2 частей: первая часть прдназначена для загрузки таблицы стилей, вторая для загрузки ключевых слов и типов. Загрузка стилей осуществляется функцией parseStyles(xmlDocPtr doc, xmlNodePtr cur, const char *name), в которой все 7 элементов описаны следующим образом:
if((!xmlStrcmp(uri, (const xmlChar *) "Plain")))
{
color = xmlGetProp(cur, (const xmlChar *)"color");
font = xmlGetProp(cur, (const xmlChar *)"font");
stylebuftemp.color = XMLValue2FLColor(color);
stylebuftemp.font = XMLValue2FLfont(font);
stylebuftemp.size = TS;
styletable[0] = stylebuftemp;
}
Функции XMLValue2FLfont(const xmlChar* XMLvalue) и XMLValue2FLColor(const xmlChar* XMLvalue) получают указатель на строку и проверяют, является ли она значением FLCOLOR или FLFONT следующим образом:
if((!xmlStrcmp(XMLvalue, (const xmlChar *)"FL_BLACK")))
{
return FL_BLACK;
}
или
if((!xmlStrcmp(XMLvalue, (const xmlChar *)"FL_COURIER")))
{
return FL_COURIER;
}
Если функция parseNodes получает указатель на элемент, содержащий значения ключевых слов, то они загружаются в массив следующим образом:
code_keywords.push_back((const char *) key). Таким же образом загружаются и типы: code_types.push_back((const char *) key).
Дата добавления: 2015-11-04; просмотров: 84 | Нарушение авторских прав
<== предыдущая страница | | | следующая страница ==> |
Формат файла проверки | | | Тестовый пример |