невозможно получить содержимое x html <script>с помощью libxml ++ с использованием выражения xpath - PullRequest
0 голосов
/ 16 января 2020
#include <libxml++/libxml++.h>

xmlpp::NodeSet xmlP(std::string xml_string, std::string xpath) {

xmlpp::DomParser doc;
// 'response' contains your HTML
doc.parse_memory(xml_string);

xmlpp::Document* document = doc.get_document();
xmlpp::Element* root = document->get_root_node();

xmlpp::NodeSet elemns = root->find(xpath);
xmlpp::Node* element = elemns[0];
std::cout << elemns.size() << std::endl;
std::cout << element->get_line() << std::endl;
//const auto nodeText = dynamic_cast<const xmlpp::TextNode*>(element);
const auto nodeText = dynamic_cast<const xmlpp::ContentNode*>(element);
if (nodeText && nodeText->is_white_space()) //Let's ignore the indenting - you don't always want to do this.
{
    std::cout << nodeText->get_content() << std::endl;
}
}

xml_string выглядит примерно так:

std::string xml_strings("
<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">
<html lang=\"en\" xml:lang=\"en\" xmlns=\"http://www.w3.org/1999/xhtml\">
<head>
<title>Demo page</title></head>
<body>
<div class=\"item\">
<div class=\"row\">
<div class=\"col-xs-8\">Item</div>
<div class=\"col-xs-4 value\">
<script type=\"text/javascript\">fruit('orange');</script>
</div></div></div>
</body></html>");

Функция вызывается со страницей и выражением xpath следующим образом: xmlpp::NodeSet xmlNodes = xmlP(xml_strings, "/html/body/div/div/div[2]/script");

Проблема в том, что я не смог получить текст внутри <script>, я попытался dynamic_cast'ing для ContentNode, ничего не помогло ...

стоит libxml ++ или мне нужно решить мою проблему с другим xml библиотека?

Пожалуйста, я ценю все предложения, которые могут дать мне текстовое значение из тега <script>.

1 Ответ

1 голос
/ 16 января 2020

Я попытался воспроизвести вашу проблему локально и не смог root->find(xpath) произвести какие-либо узлы. В соответствии с этой проблемой вы должны указать XPath, под каким пространством имен находятся ваши узлы, даже если это пространство имен по умолчанию.

Я изменил строку XPath и вызов find следующим образом:

std::string xpath("/x:html/x:body/x:div/x:div/x:div[2]/x:script");
xmlpp::Node::PrefixNsMap nsMap = {{"x",root->get_namespace_uri()}};
xmlpp::Node::NodeSet elemns = root->find(xpath, nsMap);

xmlpp::Node* element = elemns[0];
const auto nodeText = dynamic_cast<const xmlpp::Element*>(element);
if (nodeText) {
    std::cout << nodeText->get_first_child_text()->get_content() << std::endl;
}
...