Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[34.204.3.195] |
|
Сообщ.
#1
,
|
|
|
Всем доброго времени суток, есть такой xml файл:
<order> <object> <name >John Doe</name> <cost>5000</cost> </object> <object> <name>Tom Hall</name> <cost>5000</cost> </object> </order> Необходимо распарсить имена, моя наработка: size_t found = str.find("<name"); //в переменной str хранится весь xml файл string aux = str.substr(found); found = aux.find(">"); aux = aux.substr(found + 1); size_t end_found = aux.find("</name"); string find_str = aux.substr(0, end_found); Но так получаю лишь одно имя, как бы зациклить дабы получить все? |
Сообщ.
#2
,
|
|
|
Цитата skinex @ еобходимо распарсить имена, моя наработка: size_t found = str.find("<name"); //в переменной str хранится весь xml файл string aux = str.substr(found); У тебя каждый раз копируется остаток строки, работать будет очень медленно. Надо что-то типа size_t pos = 0; for (;;) { pos = str.find('<', pos); if (pos == std::string::npos) break; size_t pos2 = ++pos ............... pos = str.find('>', pos); if (pos == std::string::npos) !!!!error; std::string name(str, pos, pos2 - pos); pos2 = ++pos; ................. pos = str.find('<', pos); if (pos == std::string::npos) !!!!error; if (str[pos + 1] != '/') //Рекурсивно парсим вложенные теги, меняем значения pos, pos2 else { std::string value(str, pos, pos2 - pos); pos2 = (pos += 2); } ................................. pos = str.find('>', pos); ................................. } Пример очень грубый и нерабочий, но принцип в целом, надеюсь, должен быть понятен |
Сообщ.
#3
,
|
|
|
Сообщ.
#4
,
|
|
|
Использовать парсеры не вариант. Знаю про второй параметр find, пробовал его использовать:
while (myt < string::npos) { if (myt == string::npos) break; size_t found = myXml.find("<name", myt); string aux = myXml.substr(found); found = aux.find(">"); aux = aux.substr(found + 1); size_t end_found = aux.find("</name"); cout << end_found << endl; string find_str = aux.substr(0, end_found); myt += found + find_str.length() + end_found+4; } Но получаю довольно много выводов.... |
Сообщ.
#5
,
|
|
|
Цитата skinex @ Но получаю довольно много выводов.... Используйте второй аргумент как курсор. Он должен всё время перемещаться вправо. В вашем примере, он не двигается с места. Вот вам рабочий код, но, попытайтесь хотябы разобраться... #include <iostream> #include <string> void parse(std::string xml, std::string tag){ size_t pos1 = 0; size_t pos2 = 0; std::string OPEN_TAG = "<"+tag+">"; std::string CLOSE_TAG = "</"+tag+">"; for(;;){ pos1 = xml.find(OPEN_TAG,pos1); if(pos1 == std::string::npos){ break; } pos1+=OPEN_TAG.length(); pos2 = xml.find(CLOSE_TAG,pos1); if(pos2 == std::string::npos){ std::cout<<"Закрывающий тег '"+tag+"' отсутствует!\n"; exit(-1); } std::string value = xml.substr(pos1,pos2-pos1); std::cout<<value<<"\n"; pos1 = pos2; } } int main() { std::string xml = "<order><object><name>John Doe</name><cost>5000</cost></object><object><name>Tom Hall</name><cost>5000</cost></object></order>"; std::cout<<"start...\n"; parse(xml,"name"); return 0; } Добавлено Да, вот ровно то что я реализовал, можно смело назвать SAX-ом, уверен, есть куча примеров SAX парсеров XML файлов. То есть, даже без библиотек вы вполне могли бы их найти. Добавлено О, прошу прощения за невнимательность, я посчитал ошибкой пробел в теге, но, сейчас думаю, что вы намекнули на наличие атрибутов... В общем, вот вариант с атрибутами: #include <iostream> #include <string> void parse(std::string xml, std::string tag){ size_t pos1 = 0; size_t pos2 = 0; std::string OPEN_TAG = "<"+tag; std::string CLOSE_TAG = "</"+tag+">"; for(;;){ pos1 = xml.find(OPEN_TAG,pos1); if(pos1 == std::string::npos){ break; } pos1+=OPEN_TAG.length(); pos1 = xml.find(">",pos1); if(pos1 == std::string::npos){ std::cout<<"Закрывающая скобка тега '"+tag+"' отсутствует!\n"; exit(-2); } pos1++; pos2 = xml.find(CLOSE_TAG,pos1); if(pos2 == std::string::npos){ std::cout<<"Закрывающий тег '"+tag+"' отсутствует!\n"; exit(-1); } std::string value = xml.substr(pos1,pos2-pos1); std::cout<<value<<"\n"; pos1 = pos2; } } int main() { std::string xml = "<order><object><name>John Doe</name><cost>5000</cost></object><object><name>Tom Hall</name><cost>5000</cost></object></order>"; std::cout<<"start...\n"; parse(xml,"name"); return 0; } |