如何解析类似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的Robin Mills提供了一个perl脚本:http://dev.exiv2.org/boards/3/topics/1912?r=1923#message-1923年
这还需要解析CCD_ 1。如何在C++中实现这一点,以便在具有以下结构的dmetadata.cpp
内部的digikam中使用:
QStringList ntp = tagsPath.replaceInStrings("<Category Assigned="0">", "/");
我没有足够的编程背景来理解这一点,也没有在网上找到任何类似的代码示例。我还想将代码包含在exiv2本身中,以便其他应用程序可以从中受益。
工作代码将包含在digikam中:https://bugs.kde.org/show_bug.cgi?id=345220
您链接的代码使用了Perl的XML::Parser::Expat
模块,它是James Clark的Expat XML解析器之上的粘合层。
如果您想遵循相同的路由,您应该编写使用相同库的C++,但它可能很难使用,因为API是通过回调来使用的,您指定在传入XML流中发生某些事件时调用这些回调。您可以在Perl代码、注释process an start-of-element event
等中看到它们
链接到库后,编写与回调中的Perl等效的C代码应该很简单——它们每个都只有一行。如果您在理解Perl 时遇到问题,请打开一个新问题
还需要注意的是,Expat是一个非验证解析器,它将允许在没有注释的情况下通过格式错误的数据
考虑到最大的任务是首先解析XML数据,您可能更喜欢一种不同的解决方案,该解决方案允许您根据XML数据构建内存中的文档结构,并使用文档对象模型(DOM)对其进行查询。libxml
库允许您这样做,并且在XML::LibXML
模块中有自己的Perl粘合层
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;
}
}