parsing xml inside a node with Qt and Xquery - qt4.8

I'm trying to parse the following content with 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>");
I'm able to display the content using the following code:
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;
The output is:
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>
To print , I tried to use:
let $result := fn:doc($xmlString)//Result \
let $title := $result//dc:title/fn:string() \
return ($title )
But the result is empty.
For now, the workaround would be to get $result to pass it to another QBuffer to apply the same process.
Did I miss something obvious ?

It seems not possible to get the info in one pass because the default namespaces are different: The result requires xmlns="urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/".
For information, this is the second pass I use:
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;

Related

There are two files, pm and pl under one file. If you run the pl file, the pm package call is unsuccessful

File Directory:
/home/wh/perlstudy/perl2/Person/Student.pm
/home/wh/perlstudy/perl2/Person/person.pl
Student.pm
package Student;
use strict;
use warnings FATAL => 'all';
# use utf8;
# binmode(STDIN,"encoding(gbk)");
sub new
{
my $class = shift;
my $self = {
_name => shift, _rank => shift, };
# Print all the values just for clarification.
print "获取学生名字 $self->{_name}\n";
print "获取学生排名 $self->{_rank}\n";
bless $self, $class;
return $self;
}
sub studentRank {
my ( $self, $name ) = #_;
$self->{_name} = $name if defined($name);
return $self->{_name};
}
sub studentName {
my( $self ) = #_;
return $self->{_name};
}
1;
person.pl
#!/usr/bin/perl
use strict;
use warnings FATAL => 'all';
# use utf8;
# binmode(STDOUT,"encoding(gbk)");
BEGIN(push #INC,"/home/wh/perlstudy/perl2/Person/");
use Student;
my$object = Student->new( "Ana", "9th");
# name which is set using constructor.
my$name = $object->studentName();
print "Name set using constructor is : $name\n";
# name set using helper function.
$object->studentRank( "Anastasia" );
# getting name set by helper function.
$name = $object->studentName();
print "名字 set using helper is : $name\n";
I get:
Prototype after '#' for BEGIN : push #INC,"/home/wh/perlstudy/perl2/Person/" at perlson.pl line 6.
Want to solve the use of perl modules other than #INC.
BEGIN is a code block, so you need curly braces:
#!/usr/bin/perl
use strict;
use warnings FATAL => 'all';
# use utf8;
# binmode(STDOUT,"encoding(gbk)");
BEGIN {
push #INC, "/home/wh/perlstudy/perl2/Person/";
}
# rest of person.pl goes here
Or you use the -I flag when you call Perl:
perl -I/home/wh/perlstudy/perl2/Person/ person.pl
This has the advantage that you don't have to hard-code the path, but you'll have to re-type it each time. (Or make an alias or shell script for it.)
Or use lib:
use lib "/home/wh/perlstudy/perl2/Person/";
Finally you could install your Perl module in a place where Perl looks for modules by default, but during development you'll have to do that each time you make changes to Student.pm.

Can Saxon work on a page with .htaccess?

Due to some issues with the php version of Saxon, I currently have a convoluted setup where I do a php call to execute a java command, convert the results into html, display that html on my page, and then delete the resulting html after display. I can provide a link to the page if it helps, but the actual .xq file is pretty simplistic:
xquery version "1.0" encoding "UTF-8";
declare namespace tei="http://www.tei-c.org/ns/1.0";
declare variable $zone external;
declare variable $line external;
declare variable $collection external;
declare function local:if-empty
( $arg as item()? ,
$value as item()* ) as item()* {
if (string($arg) != '')
then data($arg)
else $value
};
declare function local:remove-elements($input as element(), $remove-names as xs:string*) as element() {
element {node-name($input) }
{$input/#*,
for $child in $input/node()[not(name(.)=$remove-names)]
return
if ($child instance of element())
then local:remove-elements($child, $remove-names)
else $child
}
};
declare function local:remove-empty-elements($nodes as node()*) as node()* {
for $node in $nodes
return
if (empty($node)) then () else
if ($node instance of element())
then if (normalize-space($node) = '')
then ()
else element { node-name($node)}
{ $node/#*,
local:remove-empty-elements($node/node())}
else if ($node instance of document-node())
then local:remove-empty-elements($node/node())
else $node
} ;
<list>
{
let $q:=collection($collection)
let $remove-list := ('note')
(:let $q:=local:remove-empty-elements($q):)
for $y in $q
let $s := $y//tei:surface
let $t := $y//tei:titleStmt/#xml:id
let $m := $y//tei:msDesc/#xml:id
let $z := $s/tei:zone[#n=$zone]
let $l := $z/tei:line[#n=$line]
let $w := concat($y//tei:msDesc/tei:msIdentifier/tei:settlement/text(),', ',$y//tei:msDesc/tei:msIdentifier/tei:institution/text(),' ',$y//tei:msDesc/tei:msIdentifier/tei:idno/text())
let $g := concat($t, "/" , $m, "/", substring-before($l/../../tei:graphic/#url,"."),".html")
let $o:=local:remove-elements($l/tei:orig,$remove-list)
where ($z//tei:line/#n = "l.1")
return
<item>{$w}: <ref target="{$g}">{$o}</ref></item>}
</list>
and the command to run it is java -Xms128m -Xmx1024m -XX:+UseCompressedOops -cp saxon9he.jar net.sf.saxon.Query -t -q:test.xq -o:1505740041.41932650059544.xml line=l.4 zone=EETS.QD.8 collection=file:<filefolder>
My problem is that the xml files I'm working with are currently unpublished transcriptions, and I'd like to keep them behind a password protected folder until I think they're ready for prime time. If I have any sort of .htaccess file in the filefolder location, I get the following error message:
Building tree for file:<filefolder>/.htaccess using class net.sf.saxon.tree.tiny.TinyBuilder
Error on line 1 column 1 of .htaccess:
SXXP0003: Error reported by XML parser: Content is not allowed in prolog.
Query failed with dynamic error: org.xml.sax.SAXParseException; systemId: file:<filefolder>/.htaccess; lineNumber: 1; columnNumber: 1; Content is not allowed in prolog.
It's pretty obvious to me that what's happening is that it's getting to the .htaccess file, which is not XML, and then doesn't know what to do with it. My question is if there's a way in my xquery file to tell Saxon not to include .htaccess in the collection. I'm sure there is, but everything I've found is about finding file names, not about suppressing them in the collection you're building.
If you ever need something more elaborate than selection using a glob pattern, then you can use the uri-collection() function to return the URIs of the files in the directory, and then use doc() to process the ones that you are actually interested in. This would give you a solution if, for example, you wanted everything that doesn't start with ".", regardless of its extension.
Another thing you can do with uri-collection() is to process each returned URI within a try/catch block so you have full control over the error handling.
Ok, I'm just stupid. The solution is to add a concat statement to append the select info to the $collection variable, like so:
let $collection:=concat($collection, '?select=*.xml')
let $q:=collection($collection)
let $remove-list := ('note')

How to fix if operation is not defined in the WSDL using php nusoap

I am currently working on a project that uses web service PHP Nusoap. I implement it at first in the local computer and it is already working perfectly fine, it can insert already in the database.Since, we are also deploying our project in the production server (Linux RHEL 4) so we also need to include the web service. In implementing this in the production server, we got this error :
Operation '' is not defined in the WSDL for this service Here is the
full details :
<?xml version="1.0" encoding="utf-8"?><SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Body>
<SOAP-ENV:Fault>
<faultcode xsi:type="xsd:string">SOAP-ENV:Client</faultcode>
<faultactor xsi:type="xsd:string"></faultactor>
<faultstring xsi:type="xsd:string">Operation &apos;&apos; is not defined in the WSDL for this service
</faultstring>
<detail xsi:type="xsd:string"></detail>
</SOAP-ENV:Fault>
HERE IS THE CODE :
client.php
<?php
require_once('lib/nusoap.php');
$data = json_decode(file_get_contents("php://input"), true);
$file_name = $data['file_name'];
$location = $data['location'];
$client = new nusoap_client('http://servername:port/WebService/server.php?wsdl', true);
if ($SERVER['REQUEST_METHOD'] == 'POST') {
$err = $client->getError();
if ($err) {
echo "<h2> Constructor error </h2><pre>" . $err. "</pre>" ;
echo "<h2> Debug </h2><pre>" . htmlspecialchars($client->getdebug(), ENT_QUOTES) . "</pre>" ;
exit();
}
$datas = array (
'file_name' => $file_name,
'location' => $location
);
$result = $client->call('InsertData', $datas);
if ($client->fault) {
echo "<h2> Fault (Expect - The request contains an invalid SOAP Body)</h2> <pre>" ;
print_r ($result);
echo "</pre>";
} else {
$err = $client->getError ();
if ($err) {
echo "<h2> Error </h2><pre>" . $err. "</pre>";
} else {
print_r ($result);
}
}
} else if ($_SERVER['REQUEST_METHOD'] != 'POST') {
echo "Method is not POST " ;
}
?>
server.php
<?php
require_once('lib.nusoap');
$server = new soap_server();
$server->configureWSDL('Database Sample Insertion', 'urn:Insert');
$server->soap_defenconding = 'UTF-8' ;
$server->register('InsertData',
array (
'file_name' => 'xsd:file_name',
'location' => 'xsd:location'
),
array ('return' => 'xsd:string'),
'urn:Insert',
'urn:Insertwsdl#InsertDate',
'rpc',
'literal'
);
function InsertData ($file_name, $location) {
$db_host = 'localhost';
$db_username = 'username';
$db_password = '' ;
$db_name = 'sample' ;
$conn = new mysqli ($db_host, $db_username, $db_password, $db_name);
if ($conn->connect_error) {
trigger_error('Database connection failed : ' .$conn->connect_error , E_USER_ERROR);
}
$sql = "INSERT INTO transaction (`filename`, `location`) VALUES ('$file_name', '$location')";
$query = $conn->query($sql);
}
$HTTP_RAW_POST_DATA = isset($HTTP_RAW_POST_DATA) ? $HTTP_RAW_POST_DATA : '' ;
$server->service($HTTP_RAW_POST_DATA);
?>
what does this problem means and how can we solve this? Or how to setup the web service PHP Nusoap in the production server? Any ideas/suggestions is appreciated. Thanks
I'v had the same problem when PHP/Apache version changed at my server. Im my case the problem was located inside nusoap library function: parse_http_headers()
There is a function used to get all HTTP headers getallheaders() and it seems not getting all headers as it should. There were no Content-Type which is required for nusoap to parse request (ex. text/xml).
Fortunately nusoap checks if function getallheaders() exists and if not it uses $_SERVER array to parse headers.
Finally the one thing I had to do was to change one line of code inside nusoap.php file to disable this function:
if (function_exists('getallheaders')){ ...
to this one:
if (0 && function_exists('getallheaders')){ ...
Hope this help others!

script score function not working but addDecayFunction is working of FunctionScore query

I am using Elastica and going to use \Elastica\Query\FunctionScore(); function score --> script_score. Here addDecayFunction() woking fine but addScriptScoreFunction() not work and not through any exception.
DecyFunction is commented because it is working
Here is code
$scriptString = "doc['geo_location'].distanceInMiles('42.946697', '-76.113623')";
$script = new \Elastica\Script($scriptString);
$query = new \Elastica\Query\FunctionScore();
$query->addScriptScoreFunction($script);
// $locationOrigin = "32.804654, -117.242594";
// $locationScale = '2mi';
// $query->addDecayFunction(\Elastica\Query\FunctionScore::DECAY_GAUSS, 'geo_location', $locationOrigin, $locationScale);
$resultSet = $type->search($query);
$results = $resultSet->getResults();
$totalResults = $resultSet->getTotalHits();
if ( $totalResults > 0 ) {
echo "<b>Total Results Found are:</b> " . $totalResults . "<br>";
foreach ( $results as $result ) {
echo $result->getScore();
$data = $result->getData();
var_dump($data);
}
}
maybe you forget to enable scripts?
script.disable_dynamic: false

How do I do a string replacement in a PowerShell function?

How do I convert function input parameters to the right type?
I want to return a string that has part of the URL passed into it removed.
This works, but it uses a hard-coded string:
function CleanUrl($input)
{
$x = "http://google.com".Replace("http://", "")
return $x
}
$SiteName = CleanUrl($HostHeader)
echo $SiteName
This fails:
function CleanUrl($input)
{
$x = $input.Replace("http://", "")
return $x
}
Method invocation failed because [System.Array+SZArrayEnumerator] doesn't contain a method named 'Replace'.
At M:\PowerShell\test.ps1:13 char:21
+ $x = $input.Replace( <<<< "http://", "")
Steve's answer works. The problem with your attempt to reproduce ESV's script is that you're using $input, which is a reserved variable (it automatically collects multiple piped input into a single variable).
You should, however, use .Replace() unless you need the extra feature(s) of -replace (it handles regular expressions, etc).
function CleanUrl([string]$url)
{
$url.Replace("http://","")
}
That will work, but so would:
function CleanUrl([string]$url)
{
$url -replace "http://",""
}
Also, when you invoke a PowerShell function, don't use parenthesis:
$HostHeader = "http://google.com"
$SiteName = CleanUrl $HostHeader
Write-Host $SiteName
Hope that helps. By the way, to demonstrate $input:
function CleanUrls
{
$input -replace "http://",""
}
# Notice these are arrays ...
$HostHeaders = #("http://google.com","http://stackoverflow.com")
$SiteNames = $HostHeader | CleanUrls
Write-Output $SiteNames
The concept here is correct.
The problem is with the variable name you have chosen. $input is a reserved variable used by PowerShell to represent an array of pipeline input. If you change your variable name, you should not have any problem.
PowerShell does have a replace operator, so you could make your function into
function CleanUrl($url)
{
return $url -replace 'http://'
}
function CleanUrl([string] $url)
{
return $url.Replace("http://", "")
}
This worked for me:
function CleanUrl($input)
{
return $input.Replace("http://", "")
}

Resources