У меня есть куча иерархических данных, хранящихся в файле 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 мне следует использовать?