无法使用 xpath 表达式获取带有 libxml++ 的 xhtml <script> 内容

can't get xhtml <script> content with libxml++ using xpath expression

#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> 标签中获取文本值的建议。

我尝试在本地重现您的问题,但无法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;
}