Разбор с использованием RapidXML

У меня есть XML-файл, который я должен анализировать, используя RapidXML и c ++. Файл представляет собой филогенетическое дерево. Каждый узел имеет узел с 1-3 дочерними узлами, каждый из которых имеет значения. Узлы могут быть научным именем, общим именем или рангом. Мой вопрос заключается в том, что, поскольку дочерние узлы для каждого узла таксономии различаются (например, у одного может быть как научное имя, так и общее имя, а у другого может быть только научное имя), как мне получить доступ к каждому значению дочерних узлов?
Например, я написал код:

for (xml_node<> * clade_node = root_node->first_node("clade"); clade_node; clade_node = clade_node->next_sibling())
{
xml_node<> * taxonomy_node = clade_node->first_node("taxonomy");

xml_node<> * sciName_node = taxonomy_node->first_node("scientific_name");
xml_node<> * comName_node = taxonomy_node->next_sibling("common_name");
xml_node<> * rank_node = taxonomy_node->next_sibling("rank");

string sciName = sciName_node->value();
string comName = comName_node->value();
string rank = rank_node->value();

}

Но я получаю ошибку потока EXC_BAD_ACCESS в строке string comName = comName_node->value() и этот метод файла RapidXML

Ch *value() const
{
return m_value ? m_value : nullstr();
}

Вот часть файла, который я анализирую:

<phylogeny rooted="true" rerootable="false">
<clade>
<clade>
<taxonomy>
<scientific_name>Neomura</scientific_name>
</taxonomy>
</clade>
<clade>
<taxonomy>
<id provider="uniprot">2</id>
<scientific_name>Bacteria</scientific_name>
<rank>superkingdom</rank>
</taxonomy>
</clade>
</clade>
</phylogeny>

Спасибо за любую помощь!

1

Решение

Если некоторые из узлов являются необязательными, вероятно, библиотека вернет NULL когда он не может найти один из них. Вы, вероятно, должны проверить, что возвращаемые значения не NULL прежде чем вы даже разыменовать указатели, чтобы получить любое возможное value():

string sciName = sciName_node->value();  // crash if scientific_name not present
string comName = comName_node->value();
string rank = rank_node->value();

Я также думаю, что использование имен в вызовах узлов / братьев и сестер немного хрупко. Может быть, лучше просто вызвать first_node / next_sibling без имени, а затем проверить имя после того, как узел действительно возвращается (проверка на NULL). Затем выполните зависящую от имени логику.

Это делает вас менее зависимым от порядка данных в XML, который может измениться в дальнейшем.

2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]