Как можно разобрать строку, подобную 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#сообщение-1923
Это также должно проанализировать Assigned="1"
. Как это можно сделать на C++ для использования в digikam, внутри dmetadata.cpp
со структурой вида:
QStringList ntp = tagsPath.replaceInStrings("<Category Assigned="0">", "/");
У меня недостаточно опыта программирования, чтобы понять это, и я не нашел в Интернете ни одного образца кода, который делает что-то подобное. Я также хотел бы включить код в сам exiv2, чтобы другие приложения могли извлечь выгоду.
Рабочий код будет включен в дигикам: https://bugs.kde.org/show_bug.cgi ?id=345220
2 ответа
Код, который вы связали, использует модуль Perl XML::Parser::Expat
, который является связующим слоем поверх Expat Джеймса Кларка. Анализатор XML.
Если вы хотите следовать тем же маршрутом, вам следует написать C++, использующий ту же библиотеку, но его использование может быть неуклюжим, поскольку API осуществляется через обратные вызовы, которые вы указываете для вызова при возникновении определенных событий во входящем потоке XML. Вы можете увидеть их в коде Perl, в комментариях process an start-of-element event
и т.д.
После того, как вы связались с библиотекой, должно быть просто написать код C, который эквивалентен Perl в обратных вызовах — каждый из них состоит только из одной строки. Пожалуйста, откройте новый вопрос, если у вас возникли проблемы с пониманием Perl.
Также обратите внимание, что Expat — это парсер без проверки, который пропускает искаженные данные без комментариев.
Учитывая, что самой большой задачей является анализ XML-данных в первую очередь, вы можете предпочесть другое решение, которое позволит вам построить структуру документа в памяти из XML-данных и опрашивать ее с помощью Объектная модель документа (DOM). Библиотека libxml
позволяет вам сделать это и имеет собственный связующий слой Perl в < модуль href="https://metacpan.org/pod/XML::LibXML" rel="nofollow noreferrer">XML::LibXML
Maik Qualmann предоставил рабочий патч для digikam!
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;
}
}
Похожие вопросы
Новые вопросы
c++
C++ — это язык программирования общего назначения. Изначально он разрабатывался как расширение C и имел аналогичный синтаксис, но теперь это совершенно другой язык. Используйте этот тег для вопросов о коде, который будет скомпилирован с помощью компилятора C++. Используйте тег версии для вопросов, связанных с конкретной стандартной версией [C++11], [C++14], [C++17], [C++20] или [C++23]. и т.д.
Category
вложены таким образом? это очень необычно