c++ - 我应该使用 XPath 还是只使用 DOM?

标签 c++ xml xpath tinyxml

我有一堆分层数据存储在一个 XML 文件中。我正在使用 TinyXML 将其包装在手工制作的类后面。给定一个将源签名描述为一组(频率,级别)对的 XML 片段,有点像这样:

<source>
  <sig><freq>1000</freq><level>100</level><sig>
  <sig><freq>1200</freq><level>110</level><sig>
</source>

我正在用这个提取对:

std::vector< std::pair<double, double> > signature() const
{
    std::vector< std::pair<double, double> > sig;
    for (const TiXmlElement* sig_el = node()->FirstChildElement ("sig");
        sig_el;
        sig_el = sig_el->NextSiblingElement("sig"))
    {
        const double level = boost::lexical_cast<double> (sig_el->FirstChildElement("level")->GetText());
        const double freq =  boost::lexical_cast<double> (sig_el->FirstChildElement("freq")->GetText());
        sig.push_back (std::make_pair (freq, level));
    }
    return sig;
}

其中 node() 指向 <source>节点。

问题:我是否可以使用 XPath 库获得更简洁、更优雅、更易于维护或以任何其他方式更好的代码片段?

更新:我尝试过使用 TinyXPath 的两种方式。他们都没有实际工作,这显然是对他们不利的一个重点。我做错了什么吗?如果这就是 XPath 的样子,我认为它对我没有任何帮助。

std::vector< std::pair<double, double> > signature2() const
{
    std::vector< std::pair<double, double> > sig;
    TinyXPath::xpath_processor source_proc (node(), "sig");
    const unsigned n_nodes = source_proc.u_compute_xpath_node_set();
    for (unsigned i = 0; i != n_nodes; ++i)
    {
        TiXmlNode* s = source_proc.XNp_get_xpath_node (i);
        const double level = TinyXPath::xpath_processor(s, "level/text()").d_compute_xpath();
        const double freq =  TinyXPath::xpath_processor(s, "freq/text()").d_compute_xpath();
        sig.push_back (std::make_pair (freq, level));
    }
    return sig;
}

std::vector< std::pair<double, double> > signature3() const
{
    std::vector< std::pair<double, double> > sig;
    int i = 1;
    while (TiXmlNode* s = TinyXPath::xpath_processor (node(), 
        ("sig[" + boost::lexical_cast<std::string>(i++) + "]/*").c_str()).
        XNp_get_xpath_node(0))
    {
        const double level = TinyXPath::xpath_processor(s, "level/text()").d_compute_xpath();
        const double freq =  TinyXPath::xpath_processor(s, "freq/text()").d_compute_xpath();
        sig.push_back (std::make_pair (freq, level));
    }
    return sig;
}

作为次要问题,如果是这样,我应该使用哪个 XPath 库?

最佳答案

一般来说,我倾向于更喜欢基于 XPath 的解决方案,因为它们的简洁性和多功能性,但老实说,在您的情况下,我认为使用 XPath 不会给您的签名带来很多。

原因如下:

代码优雅
您的代码既漂亮又紧凑,使用 XPath 表达式也不会变得更好。

内存占用
除非您的输入 XML 配置文件很大(有点矛盾)并且 DOM 解析会占用大量内存,对此没有证据表明使用 XPath 是决定性的治疗方法,否则我会坚持使用 DOM。

执行速度
在这么简单的 XML 树上,执行速度应该不相上下。 如果存在差异,则可能是 TinyXml 的优势,因为给定节点下的 freqlevel 标记的搭配。

库和外部引用这是决定性的一点。
C++ 世界中领先的 XPath 引擎是 XQilla . 它支持 XQuery(因此同时支持 XPath 1.0 和 2.0)并得到 Oracle 的支持,因为它是由负责 Berkeley DB 产品(准确地包括 Berkeley DB XML – 使用 XQilla)的小组开发的。
希望使用 XQilla 的 C++ 开发人员面临的问题是他们有多种选择

  1. 使用 Xerces 2 和 XQilla 2.1 使您的代码充满强制转换。
  2. 使用 XQilla 2.2+ 并使用 Xerces 3(此处不需要转换)
  3. 使用TinyXPath很好地与 TinyXml 集成,但是 然而,它有许多限制(例如不支持命名空间)
  4. 混合 Xerces 和 tinyXml

总而言之,在您的情况下,仅仅为了它而切换到 XPath 不会带来什么好处。

然而,XPath 是当今开发人员工具箱中非常强大的工具,没有人可以忽视它。 如果你只是想练习一个简单的例子,你的例子和任何例子一样好。然后,我会牢记以上几点,并且可能无论如何都会使用 TinyXPath

关于c++ - 我应该使用 XPath 还是只使用 DOM?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5194604/

相关文章:

c++ - 是否有公式可以确定给定 BGR 值的整体颜色? (OpenCV 和 C++)

xpath - xpath:如何选择<br>标记之前或之后的所有文本节点?\n可能吗?

c++ - 对类型 '' 的非常量左值引用无法绑定(bind)到类型 ' *' 的临时对象

java - 使用 JaxB 编码时如何避免添加特定元素/值

Java Dom 获取属性

python - 使用 lxml.etree 移动整个元素

python - selenium 计数 xpath 的元素

xml - 使用Xpath从当前XML文档中的链接文件中获取内容

C++:模板可以成为类的 friend 吗?

c++ - move 语义在这里如何工作?