Я решил использовать парсер libxml2 для моего приложения qt и im застрял в выражениях xpath. Я нашел примерный класс и методы и немного изменил его для своих нужд. Кодlibxml2 xpath parsing, не работает должным образом
QStringList* LibXml2Reader::XPathParsing(QXmlInputSource input)
{
xmlInitParser();
xmlDocPtr doc;
xmlXPathContextPtr xpathCtx;
xmlXPathObjectPtr xpathObj;
QStringList *valList =NULL;
QByteArray arr = input.data().toUtf8(); //convert input data to utf8
int length = arr.length();
const char* data = arr.data();
doc = xmlRecoverMemory(data,length); // build a tree, ignoring the errors
if(doc == NULL) { return NULL;}
xpathCtx = xmlXPathNewContext(doc);
if(xpathCtx == NULL)
{
xmlFreeDoc(doc);
xmlCleanupParser();
return NULL;
}
xpathObj = xmlXPathEvalExpression(BAD_CAST "//[@class='b-domik__nojs']", xpathCtx); //heres the parsing fails
if(xpathObj == NULL)
{
xmlXPathFreeContext(xpathCtx);
xmlFreeDoc(doc);
xmlCleanupParser();
return NULL;
}
xmlNodeSetPtr nodes = xpathObj->nodesetval;
int size = (nodes) ? nodes->nodeNr : 0;
if(size==0)
{
xmlXPathFreeContext(xpathCtx);
xmlFreeDoc(doc);
xmlCleanupParser();
return NULL;
}
valList = new QStringList();
for (int i = 0; i < size; i++)
{
xmlNodePtr current = nodes->nodeTab[i];
const char* str = (const char*)current->content;
qDebug() << "name: " << QString::fromLocal8Bit((const char*)current->name);
qDebug() << "content: " << QString::fromLocal8Bit((const char*)current->content) << "\r\n";
valList->append(QString::fromLocal8Bit(str));
}
xmlXPathFreeObject(xpathObj);
xmlXPathFreeContext(xpathCtx);
xmlFreeDoc(doc);
xmlCleanupParser();
return valList;
}
В качестве примера им сделать запрос на http://yandex.ru/ и пытаются получить узел с классом «B-domik__nojs», который является в основном один Див.
xpathObj = xmlXPathEvalExpression(BAD_CAST "//[@class='b-domik__nojs']", xpathCtx); //heres the parsing fails
проблема выражение // [@ класс = 'б-domik__nojs'] не работает. Я проверил его в firefox xpath ext., А также в опере разработки инструментов xpath ext. там это выражение работает отлично. Я также пытался получить другие узлы с атрибутами, но по какой-то причине xpath для ANY-атрибута терпит неудачу. Что-то не так в моем методе? Также, когда я загружаю дерево с помощью xmlRecover, он дает мне много ошибок парсера в отладочном выходе.
Ok я играл немного с моей функцией libxml2 больше и используются «// *» выражение, чтобы получить все элементы документа, но! Он возвращает мне только элементы в первом дочернем узле тега body. This is the yandex.ru dom tree
так что в основном он получает ВСЕ элементы в первом div «div class =« b-line b-line_bar », но по каким-то причинам не ищет другие элементы в других дочерних узлах. Почему это может произойти Возможно, xmlParseMemory по какой-то причине не строит полное дерево? Существует ли какое-либо возможное решение для исправления этого вопроса.
Ok. Небольшое обновление, я прошел дерево, и я понял, что он НЕ МОЖЕТ полностью построить функцию 'xmlRecoverMemory'. Он создает только html, head, body и first 'div' в дереве. Так что мой вопрос в том, что теперь, как я могу построить валидное дерево, игнорируя все ошибки ??? – SirLanceloaaat