Разбирать ACDSee категории

Как можно проанализировать xml-подобную строку и преобразовать ее в отдельный список?

Я пытаюсь преобразовать следующую строку:

<Categories>
  <Category Assigned="0">
    6 Level
    <Category Assigned="1">
      6.2 Level
      <Category Assigned="0">
        6.3 Level
        <Category Assigned="0">
          6.4 Level
          <Category Assigned="1">
            6.5 Level
          </Category>
        </Category>
      </Category>
    </Category>
  </Category>
</Categories>

В отдельный список вроде:

6 Level/6.2 Level/6.3 Level/6.4 Level/6.5 Level, 6 Level/6.2 Level

Робин Миллс из exiv2 предоставил Perl-скрипт: http://dev.exiv2.org/boards/3/topics/1912?r=1923

Это нужно будет также разобрать Assigned="1", Как это можно сделать в C++ для использования в дигиках, внутри dmetadata.cpp со структурой как:

    QStringList ntp = tagsPath.replaceInStrings("<Category Assigned="0">", "/");

У меня нет достаточного опыта программирования, чтобы понять это, и я не нашел ни одного примера кода онлайн, который бы делал что-то подобное. Я также хотел бы включить код в сам exiv2, чтобы другие приложения могли получить выгоду.

Рабочий код будет включен в дигикам: https://bugs.kde.org/show_bug.cgi?id=345220

2 ответа

Код, который вы связали, использует Perl XML::Parser::Expat модуль, который является связующим слоем поверх XML-парсера Expat Джеймса Кларка.

Если вы хотите следовать по тому же маршруту, вы должны написать C++, который использует ту же библиотеку, но это может быть неуклюже для использования, так как API - через обратные вызовы, которые вы указываете для вызова при возникновении определенных событий во входящем потоке XML. Вы можете увидеть их в коде Perl, прокомментировал process an start-of-element event и т.п.

После того, как вы связались с библиотекой, должно быть просто написать код C, который эквивалентен Perl в обратных вызовах - они представляют собой одну строку. Пожалуйста, откройте новый вопрос, если у вас есть проблемы с пониманием Perl

Также обратите внимание, что Expat - это не проверяющий парсер, который пропускает искаженные данные без комментариев.

Учитывая, что самая главная задача - это, в первую очередь, анализ данных XML, вы можете предпочесть другое решение, которое позволит вам построить структуру документа в памяти из данных XML и опросить ее, используя объектную модель документа (DOM). libxml библиотека позволяет вам сделать это, и имеет свой собственный слой клея Perl в XML::LibXML модуль

Maik Qualmann предоставил рабочий патч для дигикам!

QString xmlACDSee = getXmpTagString("Xmp.acdsee.categories", false);
if (!xmlACDSee.isEmpty())
{
    xmlACDSee.remove("</Categories>");
    xmlACDSee.remove("<Categories>");
    xmlACDSee.replace("/", "|");

    QStringList tagsXml = xmlACDSee.split("<Category Assigned");
    int category        = 0;
    int length;
    int count;

    foreach(const QString& tags, tagsXml)
    {
        if (!tags.isEmpty())
        {
            count  = tags.count("<|Category>");
            length = tags.length() - (11 * count) - 5;

            if (category == 0)
            {
                tagsPath << tags.mid(5, length);
            }
            else
            {
                tagsPath.last().append(QString("/") + tags.mid(5, length));
            }

            category = category - count + 1;

            if (tags.left(5) == QString("=\"1\">") && category > 0)
            {
                tagsPath << tagsPath.value(tagsPath.size() - count - 1);
            }
        }
    }

    if (!tagsPath.isEmpty())
    {
        return true;
    }
}
Другие вопросы по тегам