У меня есть несколько документов XML со следующим стилем, но каждый из них содержит разные узлы.
<Protocol version = "1.02">
<property name = "Name">
<QString>Example</QString>
</property>
<property name = "Description">
<QString/>
</property>
<property name = "This goes deep">
<class type = "Deeper">
<property name = "Deep name">
<QString> data </QString>
</property>
// ...
</class>
</property>
Я анализирую это с QDomElement / QDomNode. Мне нужно получить атрибуты и значения узлов из дерева (которое, как я уже говорил, неизвестно, и мы говорим о сотнях файлов). У меня нет проблем с получением значений:
QString MMainForm::processXmlElement( const QDomElement& aElement ) const
{
QString ret ="";
QDomNode node = aElement.firstChild();
while ( !node.isNull() )
{
QDomElement e = node.toElement();
if ( node.childNodes().size() > 0 )
{
ret += processXmlElement( e );
}
else
{
ret += node.nodeValue() + "\n";
}
node = node.nextSibling();
}
return ret;
}
Но получение атрибутов (например, текста «Глубокое имя») действительно сбивает меня с толку. Я знаю, что есть функция :: attribute () для QDomElement, но результирующая карта всегда содержит только пустую строку. Следующий код демонстрирует концепцию того, как я пытался извлечь атрибуты:
QString MMainForm::getAttributes( const QDomElement& aElement ) const
{
QString ret = "";
auto var = aElement.attributes();
for ( int i=0; i < var.count(); ++i)
{
ret += var.item( i ).toText().data() + '\n';
}
return ret;
}
Это концептуально правильно? Как бы вы пошли извлекать все атрибуты в хороший список / строку?
Поскольку вы перебираете коллекцию QDomNode
того же типа (QDomAttr
), вы можете позвонить nodeName()
а также nodeValue()
методы для каждого элемента:
auto var = aElement.attributes();
for ( int i=0; i < var.count(); ++i)
{
ret += var.item(i).nodeName() + ": " + var.item(i).nodeValue() + '\n';
}
Или вы можете разыграть каждый предмет на QDomAttr
и использовать name
а также value
свойства:
auto var = aElement.attributes();
for ( int i=0; i < var.count(); ++i)
{
QDomAttr attribute = var.item(i).toAttr();
ret += attribute.name() + ": " + attribute.value() + "\n";
}
Других решений пока нет …