Парсинг xml внутри узла с помощью Qt и Xquery
Я пытаюсь разобрать следующий контент с Qt4.8.
QString l_dynamicResult("<?xml version=\"1.0\"?>\
<u:BrowseResponse xmlns:u=\"urn:schemas-upnp-org:service:ContentDirectory:1\">\
<Result><DIDL-Lite xmlns="urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:upnp="urn:schemas-upnp-org:metadata-1-0/upnp/" xmlns:sec="http://www.sec.co.kr/" xmlns:dlna="urn:schemas-dlna-org:metadata-1-0/"><container id="0/1" parentID="0" restricted="1"><dc:title>Fichiers</dc:title><upnp:class>object.container.storageFolder</upnp:class></container><container id="0/0" parentID="0" restricted="1"><dc:title>TV</dc:title><upnp:class>object.container.storageFolder</upnp:class></container><container id="0/5" parentID="0" restricted="1"><dc:title>Flux RSS</dc:title><upnp:class>object.container.storageFolder</upnp:class></container></DIDL-Lite></Result>\
<NumberReturned>3</NumberReturned>\
<TotalMatches>3</TotalMatches>\
<UpdateID>0</UpdateID>\
</u:BrowseResponse>");
Я могу отобразить содержимое, используя следующий код:
QByteArray l_array;
QBuffer l_buffer(&l_array);
l_buffer.setData(l_dynamicResult.toUtf8());
l_buffer.open(QIODevice::ReadOnly);
l_info = "declare namespace xs='http://www.w3.org/2001/XMLSchema';\
declare namespace fn='http://www.w3.org/2005/xpath-functions';\
declare namespace dc='http://purl.org/dc/elements/1.1';\
let $result := fn:doc($xmlString)//Result/fn:string() \
return ($result ) ";
QStringList l_cdsContent;
l_q.bindVariable("xmlString", &l_buffer);
l_q.setQuery(l_info);
l_res = l_q.evaluateTo(&l_cdsContent);
Log("query res=")<<(l_res ?"Ok":"error");
qDebug()<<"l_cdsContent="<<l_cdsContent;
Выход:
l_cdsContent=<DIDL-Lite xmlns="urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:upnp="urn:schemas-upnp-org:metadata-1-0/upnp/" xmlns:sec="http://www.sec.co.kr/" xmlns:dlna="urn:schemas-dlna-org:metadata-1-0/"><container id="0/1" parentID="0" restricted="1"><dc:title>Fichiers</dc:title><upnp:class>object.container.storageFolder</upnp:class></container><container id="0/0" parentID="0" restricted="1"><dc:title>TV</dc:title><upnp:class>object.container.storageFolder</upnp:class></container><container id="0/5" parentID="0" restricted="1"><dc:title>Flux RSS</dc:title><upnp:class>object.container.storageFolder</upnp:class></container></DIDL-Lite>
Для печати я попытался использовать:
let $result := fn:doc($xmlString)//Result \
let $title := $result//dc:title/fn:string() \
return ($title )
Но результат пуст.
На данный момент, обходной путь должен был бы получить $result
передать его другому QBuffer, чтобы применить тот же процесс.
Я что-то упустил очевидное?
1 ответ
Кажется, невозможно получить информацию за один проход, потому что пространства имен по умолчанию отличаются: результат требует xmlns="urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/"
,
Для информации, это второй проход, который я использую:
QByteArray l_array1;
QBuffer l_buffer1(&l_array1);
QString l_xml(l_cdsContent.at(0));
l_buffer1.setData(l_xml.toUtf8());
l_buffer1.open(QIODevice::ReadOnly);
l_info = "declare default element namespace 'urn:schemas-upnp-org:metadata-1-0/DIDL-Lite' ;\
declare namespace fn='http://www.w3.org/2005/xpath-functions';\
declare namespace dc='http://purl.org/dc/elements/1.1';\
declare namespace upnp='urn:schemas-upnp-org:metadata-1-0/upnp';\
declare namespace sec='http://www.sec.co.kr';\
declare namespace dlna='urn:schemas-dlna-org:metadata-1-0';\
for $i in fn:doc($xmlString1)//node() \
let $title := if (fn:compare(fn:name($i ), 'dc:title')=0) \
then $i/fn:string() \
else ()\
let $id := if (fn:compare(fn:name($i ), 'container')=0) \
then $i/@id/fn:string() \
else () \
return ($id, $title)\
";
QXmlQuery l_q1;
l_q1.bindVariable("xmlString1", &l_buffer1);
l_q1.setQuery(l_info);
QStringList l_result;
l_res = l_q1.evaluateTo(&l_result);
Log("query res=")<<(l_res ?"Ok":"error");
qDebug()<<"l_result="<<l_result;