Как разобрать неизвестный xml в Qt и получить все атрибуты в нем?

У меня есть несколько документов 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;
}

Это концептуально правильно? Как бы вы пошли извлекать все атрибуты в хороший список / строку?

1 ответ

Решение

Поскольку вы перебираете коллекцию 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";
}
Другие вопросы по тегам