MediaServer CDSでBrowseした結果を解析する(XML::DOMを利用)
ここでは、CDS(Content Directory Service)に対してBrowseした結果のResult Argumentに含まれるXMLを解析する方法を説明したいと思います。 ここでは、XML::DOMを使っています。 (Net::UPnP::AV::MediaServerというperlモジュールもありましたが、細かい事をやろうとすると色々出来なさそうなので自前でパースする道を選びました。)
以下のサンプルでは、XMLに含まれるノード名を列挙して行っています。 これによって、例えば、dc:titleやupnp:classなどの内容を取得する事ができます。
ObjectID(id)等はAttribute(アトリビュート/属性)としてコンテナやアイテムに含まれるものなので、このサンプルでは表示されません。
サンプルコード
サンプルです。
#!/usr/bin/perl
use Net::UPnP::ControlPoint;
use XML::DOM;
$upnp = Net::UPnP::ControlPoint->new();
@devs = $upnp->search(st => 'upnp:rootdevice', mx => 3);
foreach $dev (@devs) {
$type = $dev->getdevicetype();
if ($type ne 'urn:schemas-upnp-org:device:MediaServer:1') {
next;
}
$serv = $dev->getservicebyname(
'urn:schemas-upnp-org:service:ContentDirectory:1');
unless ($serv) {
next;
}
print $dev->getfriendlyname();
print "\n";
$inarg{'ObjectID'} = "0";
$inarg{'BrowseFlag'} = "BrowseDirectChildren";
$inarg{'Filter'} = "";
$inarg{'StartingIndex'} = "0";
$inarg{'RequestedCount'} = "0";
$inarg{'SortCriteria'} = "";
$resp = $serv->postaction('Browse', \%inarg);
if ($resp->getstatuscode() != 200) {
print "ERROR : status code ";
print $resp->getstatuscode();
print "\n";
next;
}
$args = $resp->getargumentlist();
print $args->{'Result'};
print "\n";
print $args->{'NumberReturned'};
print "\n";
print $args->{'TotalMatches'};
print "\n";
print $args->{'UpdateID'};
print "\n";
print "===\n";
print "Print Result\n";
print "===\n";
$parser = new XML::DOM::Parser;
$doc = $parser->parse($args->{'Result'});
$didl = $doc->getFirstChild();
$nodes = $didl->getChildNodes();
for ($i=0; $i<$nodes->getLength(); $i++) {
$node = $nodes->item($i);
print $node->getNodeName();
print "\n";
$cn = $node->getChildNodes();
for ($k=0; $k<$cn->getLength(); $k++) {
$childNode = $cn->item($k);
print " " . $childNode->getNodeName();
print "\n";
$text = $childNode->getFirstChild();
if ($text->getNodeType == TEXT_NODE) {
print " " . $text->getData();
print "\n";
}
}
}
}
exit;