У меня есть 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>
Спасибо за любую помощь!
Если некоторые из узлов являются необязательными, вероятно, библиотека вернет 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, который может измениться в дальнейшем.
Других решений пока нет …