How to parse dynamic response using QtSoap? - qt

I have currently the response of type:
<?xml version=\"1.0\" encoding=\"utf-8\"?><soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"><soap:Body><StartBuisnessResponse xmlns=\"http://test.com/kerosene/mytest/\"><StartBuisnessResult><Commodity><_price>45</_price></Commodity><Commodity><_price>36</_price></Commodity></StartBuisnessResult></StartBuisnessResponse></soap:Body></soap:Envelope>
Here, the node is dynamic. In such a case, I am not able to find a way to parse the response SOAP XML using QtSoap.
This is the Code which works for fetching the first commodity:
QString str("<?xml version=\"1.0\" encoding=\"utf-8\"?><soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"><soap:Body><StartBuisnessResponse xmlns=\"http://cg.nic.in/kerosene/finotest/\"><StartBuisnessResult><Commodity><_price>45</_price></Commodity><Commodity><_price>36</_price></Commodity></StartBuisnessResult></StartBuisnessResponse></soap:Body></soap:Envelope>");
QByteArray *arr = new QByteArray();
arr->append(str);
QtSoapMessage *testMsg = new QtSoapMessage();
testMsg->setContent(*arr);
const QtSoapType &testCont = testMsg->returnValue();
const QtSoapType &price = testCont["Commodity"];
qDebug() << "The value of the _price here is " << price["_price"].value().toString();
But how do I traverse through the subsequent nodes in this case? Any idea?

If you follow the example shown on Qt Solutions QtSoap that they have for Google, you should be on your way with it.
http://doc.qt.digia.com/solutions/4/qtsoap/index.html
http://doc.qt.digia.com/solutions/4/qtsoap/google-example.html
An alternative if you don't want to try that is to use the QXmlStreamReader:
http://qt-project.org/doc/qt-4.8/qxmlstreamreader.html#details
Here is some quick code to get out the _price information from this:
// add "QT += xml" to your .pro
#include <QXmlStreamReader>
#include <QDebug>
QXmlStreamReader xml(str);
while (!xml.atEnd())
{
if (xml.readNextStartElement())
qDebug() << qPrintable(xml.name().toString());
if(xml.name().toString() == "_price")
{
qDebug() << "\t" << xml.readElementText().toInt();
}
}
You also have a number of other alternatives available, too. See Qt XML Processing.
Hope that helps.

Related

Calling a method from a different .cpp file

I want to save some data as a text file, the first txt file will contain header information, the other text file will save data streamed from sensors, so with the help from the internet I created the following "datalogger.cpp" file
#include "datalogger.h"
#include <QDebug>
#include <iostream>
#include <QFile>
DataLogger::DataLogger(QObject *parent) : QObject(parent)
{
}
DataLogger::~DataLogger(){
}
void DataLogger::save(DataStream &input){
saveAsText(input);
}
void DataLogger::saveAsText(DataStream &input){
QTextStream outHeader(&outFileHeader);
outHeader << "[CAPTURE SETTINGS]\n"
<< "Filename: " << SettingsSingleton::instance().getFileName() << ".txt \n"
<< "Samples: " << QString::number(input.size()) << "\n"
<< "Duration: " << QString::number(input.back().time) << "ms \n"
<< "Sample rate: " << QString::number(SettingsSingleton::instance().getSampleRate()) << " Hz\n"
<< "Source: " << SettingsSingleton::instance().getSource() << "\n"
outFileHeader.close();
}
QFile outFile(SettingsSingleton::instance().getFileName() + ".txt");
QTextStream out(&outFile);
for (int i ; i<input.size();i++){
const EcgStreamObject tmp=input.at(i);
out << tmp.toText() << endl; //"\n";
}
outFile.close();
}
}
I have my "DataStream" input variable that I want to pass to the method and save as a ".txt" file, however I do no know how to call the method "void DataLogger::save(DataStream &input)" from a different ".cpp" file where the DataStream variable is located.
I am extremely new to c++ please it as simple as possible please.
Thank you in advance
If I get your question right, it is about how to create and use a header file in c++.
There is already a lot of information about this, for example this article from cplusplus.com or this from learncpp.com.
All you should need to do is add "datalogger.h" to your other file.
When you call the method DataLogger::save from your other file, the program will search for an implementation that was linked to your program (i.e. the file you posted here) and use that to actually perform the work.
Stefan's answer is probably important to look at too as it will cover this case and some other basics if you are going to be working in C/C++ long term.

DicomImage's writeBMP function produces unclear gray image

I am using DCMTK to read and hopefully modify DICOM images. I have the following code:
#include <iostream>
#include <opencv\cv.h>
#include <dcmtk\dcmimgle\dcmimage.h>
int main() {
try {
DicomImage* dicomImage = new DicomImage("C:/Users/Kriselle/Documents/000004.dcm");
if ((dicomImage != NULL) && (dicomImage->isMonochrome())) {
dicomImage->writeBMP("C:/Users/Kriselle/Documents/z.bmp", 8);
std::cout << "z.bmp is created" << std::endl;
}
else {
std::cout << "dicomImage is null or not monochrome" << std::endl;
}
}
catch (cv::Exception e) {
std::cerr << e.what() << std::endl;
}
return 0;
}
All I did was create a DicomImage and write its pixel data to a BMP file with the filename I specified but the image returns only a gray image with the outline of the original image barely recognized.
This is what it should look like: https://www.dropbox.com/s/6dw8nlae8hfvqf6/000004.jpg?dl=0
This is what the code produces: https://www.dropbox.com/s/fff2kch124bzjqy/z.bmp?dl=0
Am I missing something in the code or did I not understand what the function does? Can anyone please enlighten me? Thank you very much!
As you can read in the API documentation of the DicomImage class, the default is that no VOI transformation is enabled when rendering monochrome DICOM images. In your case, this seems to be inappropriate, so you should specify a more appropriate VOI setting (e.g. a min-max window) or use one of the VOI windows stored in the DICOM dataset (if any).
By the way, after loading the image in the constructor, you should also check the status of this process using the getStatus() method.

Read exif metadata of images in Qt

In my Qt app I want to read exif data of images. QImage or QPixmap don't seem to provide such hooks.
Is there any API in Qt that allows reading exif without using external libraries like libexif?
EDIT: This is a duplicate of this
For me, the best choice was easyexif by Mayank Lahiri. You only need to add two files exif.cpp and exif.h to your project.
int main(int argc, char *argv[])
{
for (int i=1; i<argc; ++i){
QFile file(argv[i]);
if (file.open(QIODevice::ReadOnly)){
QByteArray data = file.readAll();
easyexif::EXIFInfo info;
if (int code = info.parseFrom((unsigned char *)data.data(), data.size())){
qDebug() << "Error parsing EXIF: code " << code;
continue;
}
qDebug() << "Camera model : " << info.Model.c_str();
qDebug() << "Original date/time : " << info.DateTimeOriginal.c_str();
} else
qDebug() << "Can't open file:" << argv[i];
}
return 0;
}
Try QExifImageHeader from qt extended framework. qtextended.org is not available for me? but you may search for other download mirrows.
QImageReader has a method named transformation() which is introduced in version 5.5, first you should try that.
You can also check the following link to see how it's done using Windows GDI in Qt, http://amin-ahmadi.com/2015/12/17/how-to-read-image-orientation-in-qt-using-stored-exif/

Qt XQuery into a QStringList

I'm trying to use QtXmlQuery to extract some data from XML. I'd like to put this into a QStringList. I try the following:
QByteArray in = "this is where my xml lives";
QBuffer received;
received.setData(in);
received.open(QIODevice::ReadOnly);
QXmlQuery query;
query.bindVariable("data", &received);
query.setQuery(NAMESPACE //contains definition of the t namespace
"doc($data)//t:service/t:serviceID/text()");
QBuffer outb;
outb.open(QIODevice::ReadWrite);
QXmlSerializer s(query, &outb);
query.evaluateTo(&s);
qDebug() << "buffer" << outb.data(); //This works perfectly!
QStringList * queryResult = new QStringList();
query.evaluateTo(queryResult);
qDebug() << "string list" << *queryResult; //This gives me no output!
As you can see, everything works fine when I send the output into a QBuffer via a QXmlSerializer... but I get nothing when I try to use a QStringList.
Try to use string() instead of text(), it should work.

How to get magic number of a binary file

There is a magic number associated with each binary file , does anyone know how to retrieve this information from the file?
file <file_name>
magic numbers are usually stored in (linux):
/usr/share/file/magic
also check this link, someone was trying to use libmagic to get the information in C program, might be useful if you're writing something yourself.
Use libmagic from the file package to try and sniff out the type of file if that's your goal.
There are no general "magic" numbers in binary files on unix, though different formats might define their own. The above library knows about many of those and also use various other heuristics to try and figure out the format/type of file.
The unix file command uses magic number. see the file man page for more.(and where to find the magic file )
Read this: http://linux.die.net/man/5/magic
It's complex, and depends on the specific file type you're looking for.
There is a file command which in turn uses a magic library, the magic library reads from a file found in /etc called magic (this is installation dependant and may vary), which details what are the first few bytes of the file and tells the file what kind of a file it is, be it, jpg, binary, text, shell script. There is an old version of libmagic found on sourceforge. Incidentally, there is a related answer to this here.
Hope this helps,
Best regards,
Tom.
Expounding on #nos's answer:
Example below uses the default magic database to query the file passed on the command line. (Essentially an implementation of the file command. See man libmagic for more details/functions.
#include <iostream>
#include <magic.h>
#include <cassert>
int main(int argc, char **argv) {
if (argc == 1) {
std::cerr << "Usage " << argv[0] << " [filename]" << std::endl;
return -1;
}
const char * fname = argv[1];
magic_t cookie = magic_open(0);
assert (cookie !=nullptr);
int rc = magic_load(cookie, nullptr);
assert(rc == 0);
auto f= magic_file(cookie, fname);
if (f ==nullptr) {
std::cerr << magic_error(cookie) << std::endl;
} else {
std::cout << fname << ' ' << f << std::endl;
}
}

Resources