我试图通过解析 XML 库(iTunes 目录中的 iTunes Music Library.xml)来获取 iTunes 专辑列表。
#include <iostream>
#include <QtCore>
#include <QFile>
#include <QtXml>
using namespace std;
void parse(QDomNode n) {
while(!n.isNull()) {
// If the node has children
if(n.hasChildNodes() && !n.isNull()) {
// We get the children
QDomNodeList nChildren = n.childNodes();
// We print the current tag name
//std::cout << "[~] Current tag : <" << qPrintable(n.toElement().tagName()) << ">" << std::endl;
// And for each sub-tag of the current tag
for(int i = 0; i < nChildren.count(); i++) {
// We get the children node
QDomNode nChild = nChildren.at(i);
// And the tag value (we're looking for *Album* here)
QString tagValue = nChild.toElement().text();
// If the tag isn't null and contain *Album*
if(!nChild.isNull() && tagValue == "Album") {
// The album name is in the next tag
QDomElement albumNode = nChild.nextSiblingElement();
std::cout << "[-] Album found -> " << qPrintable(albumNode.text()) << std::endl;
}
// And we parse the children node
parse(nChild);
}
}
n = n.nextSibling();
}
}
int main() {
QDomDocument doc("Lib");
QFile file("/Users/wizardman/QtRFIDMusic/Lib.min.xml");
if(!file.open(QIODevice::ReadOnly))
return 1;
if(!doc.setContent(&file)) {
file.close();
return 1;
}
file.close();
// Root element
QDomElement docElem = doc.documentElement();
// <plist> -> <dict>
QDomNode n = docElem.firstChild().firstChild();
cout << endl << "Album list" << endl;
cout << "------------------------------------" << endl;
parse(n);
return 0;
}
<key>Album</key>
iTunes 的 XML 并不是真正的标准 XML,专辑名称存储在每个条目旁边的节点中。这是它的样子。我故意重命名了一些节点以进行调试(以查看是否在输出中到达它们)。
这是我的输出:
Album list
------------------------------------
[-] Album found -> J Dilla - Legacy Vol.1
[-] Album found -> J Dilla - Legacy Vol.2
[-] Album found -> J Dilla - Legacy Vol.1
[-] Album found -> J Dilla - Legacy Vol.2
[-] Album found -> J Dilla - Legacy Vol.2
[-] Album found -> J Dilla - Legacy Vol.2
我不明白为什么循环正在重新解析第一个节点。有任何想法吗 ?