我应该使用 XPath 还是只使用 DOM?

2023-12-25

我有一堆分层数据存储在 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> node.

问题:使用 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 会给您带来很多好处。signature.

原因如下:

代码优雅
您的代码很好而且很紧凑,使用 XPath 表达式不会变得更好。

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

执行速度
在这样一个简单的 XML 树上,执行速度应该是相当的。 如果存在差异,则可能是 TinyXml 的优势,因为freq and level给定节点下的标签。

库和外部参考这就是决定性的一点。
C++ 世界中领先的 XPath 引擎是XQilla http://xqilla.sourceforge.net/HomePage。 它支持 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. use 小XPath http://tinyxpath.sourceforge.net/与 TinyXml 很好地集成,但是 然而,存在许多限制(例如不支持命名空间)
  4. 混合 Xerces 和tinyXml

总之,在您的情况下,仅仅为了它而切换到 XPath 不会带来任何好处(如果有的话)。

然而,XPath 是当今开发人员工具箱中一个非常强大的工具,没有人可以忽视它。 如果您只想练习一个简单的示例,那么您的示例就很好了。然后,我会记住上面的几点并可能使用小XPath anyway.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

我应该使用 XPath 还是只使用 DOM? 的相关文章

随机推荐