How can deal with such xml files?
-
wrote on 23 Jul 2017, 01:59 last edited by
-
Wish you can help me with two problems!
1.How can I read the size information in such xml files ?
2.How can I generate such xml files? -
wrote on 23 Jul 2017, 03:54 last edited by
I find it really complex to deal with xml files, but let me try!
Thank you! -
wrote on 23 Jul 2017, 09:59 last edited by
@joeQ
I‘ve tried to read four values from the 0.xml,xmin,ymin,xmax and ymax in "bndbox", and tp draw a rectangle with them.But it doesn't work. I've debuged only to find that I cannot get those values, though the reader can find "bndbox" well. There must have been something wrong in small details, could you please help me to figure out?The class ParseXml is used in ImageWidget.
//parsexml.h #pragma once #include <QXmlStreamReader> #include <QMessageBox> #include <QString> #include <QFile> class ParseXml { public: ParseXml(void); ParseXml(QString fileName); ~ParseXml(void); void ReadFile(const QString &fileName); void ReadAnnotation(); void ReadObject(); void ReadBndbox(); void Skip(); QPoint get_start_point(); QPoint get_end_point(); private: QXmlStreamReader reader; int m_xmin; int m_ymin; int m_xmax; int m_ymax; };
//parsexml.cpp #include "ParseXml.h" ParseXml::ParseXml(void) { } ParseXml::ParseXml(QString fileName) { ReadFile(fileName); } ParseXml::~ParseXml(void) { } void ParseXml::ReadFile(const QString &fileName) { QFile file(fileName); if (file.open(QIODevice::ReadOnly|QIODevice::Text)) { reader.setDevice(&file); while (!reader.atEnd()) { if (reader.isStartElement()) { if (reader.name()=="annotation") { ReadAnnotation(); } else { reader.raiseError(QObject::tr("Not a valid annotation file")); } } else { reader.readNext(); } } file.close(); } } void ParseXml::ReadAnnotation() { reader.readNext(); while(!reader.atEnd()) { if (reader.isEndElement()) { reader.readNext(); break; } if (reader.isStartElement()) { if (reader.name()=="object") { ReadObject(); } else { Skip(); } } else { reader.readNext(); } } } void ParseXml::ReadObject() { reader.readNext(); while (!reader.atEnd()) { if (reader.isEndElement()) { reader.readNext(); break; } if (reader.isStartElement()) { if (reader.name()=="bndbox") { ReadBndbox(); } else { Skip(); } } else { reader.readNext(); } } } void ParseXml::ReadBndbox() { int points[4]; for (int i=0;i<4;i++) { reader.readNext(); points[i] = reader.readElementText().toInt(); reader.readNext(); } m_xmin = points[0]; m_ymin = points[1]; m_xmax = points[2]; m_ymax = points[3]; } void ParseXml::Skip() { reader.readNext(); while(!reader.atEnd()) { if (reader.isEndElement()) { reader.readNext(); break; } if (reader.isStartElement()) { Skip(); } else { reader.readNext(); } } } QPoint ParseXml::get_start_point() { return QPoint(m_xmin,m_ymin); } QPoint ParseXml::get_end_point() { return QPoint(m_xmax,m_ymax); }
//imagewidget.h #ifndef IMAGEWIDGET_H #define IMAGEWIDGET_H #include <QWidget> #include <QImage> #include <vector> #include <QPainter> #include <QFileDialog> #include <QMouseEvent> #include <QMessageBox> #include <QXmlStreamReader> #include <QToolTip> #include "ui_imagewidget.h" #include "Rect.h" #include "ParseXml.h" using namespace std; class ImageWidget : public QWidget { Q_OBJECT public: ImageWidget(QWidget *parent = 0); ~ImageWidget(); public slots: void Open(); void Save(); void SaveAnnotation(); void ReadXml(); void SaveXml(); void Delete(); void paintEvent(QPaintEvent *); void mousePressEvent(QMouseEvent *event); void mouseMoveEvent(QMouseEvent *event); void mouseReleaseEvent(QMouseEvent *event); private: Ui::ImageWidget ui; QImage *ptr_image; QImage *ptr_save; QPoint m_Start; QPoint m_End; bool draw_status; bool load_status; vector<Rect*> rect_array; }; #endif // IMAGEWIDGET_H
//imagewidget.cpp #include "imagewidget.h" ImageWidget::ImageWidget(QWidget *parent) : QWidget(parent) { ui.setupUi(this); ptr_image = new QImage(); ptr_save = new QImage(); draw_status = false; load_status = false; setMouseTracking(true); } ImageWidget::~ImageWidget() { for (int i=0;i<rect_array.size();i++) { if (rect_array[i]) { delete rect_array[i]; rect_array[i] = NULL; } } } void ImageWidget::Open() { QString fileName = QFileDialog::getOpenFileName(this,tr("Read Image"),".",tr("Image(*.bmp *.png *.jpg)")); if (!fileName.isEmpty()) { ptr_image->load(fileName); load_status = true; } update(); } void ImageWidget::Save() { QString fileName = QFileDialog::getSaveFileName(this,tr("Save Image"),".",tr("Image(*.bpm *.png *.jpg)")); if (!fileName.isEmpty()) { ptr_save->save(fileName); } } void ImageWidget::SaveAnnotation() { } void ImageWidget::ReadXml() { QString fileName = QFileDialog::getOpenFileName(this,tr("Read Xml File"),".",tr("Xml(*.xml)")); ParseXml parsexml_(fileName); m_Start = parsexml_.get_start_point(); m_End = parsexml_.get_end_point(); } void ImageWidget::SaveXml() { QString fileName = QFileDialog::getSaveFileName(this,tr("Save Xml File"),".",tr("Xml(*.xml)")); } void ImageWidget::Delete() { if (!rect_array.empty()) { rect_array.pop_back(); } } void ImageWidget::mousePressEvent(QMouseEvent *event) { if (Qt::LeftButton==event->button()&&load_status) { draw_status = true; m_Start = m_End = event->pos(); } } void ImageWidget::mouseMoveEvent(QMouseEvent *event) { QToolTip::showText(event->globalPos(),QString::number( event->pos().x() ) + ", " +QString::number( event->pos().y() ),this, rect() ); QWidget::mouseMoveEvent(event); if (draw_status) { m_End = event->pos(); } } void ImageWidget::mouseReleaseEvent(QMouseEvent *event) { Rect *current_rect = NULL; current_rect = new Rect(m_Start,m_End); rect_array.push_back(current_rect); draw_status = false; } void ImageWidget::paintEvent(QPaintEvent *) { *ptr_save = *ptr_image; QPen pen; QPainter painter(this); QPainter paintImage(ptr_save); QRect image_rect(0,0,ptr_image->width(),ptr_image->height()); pen.setWidth(5); pen.setColor(Qt::red); painter.setPen(pen); paintImage.setPen(pen); painter.begin(this); paintImage.begin(ptr_save); painter.drawImage(image_rect,*ptr_image); painter.drawRect(m_Start.rx(),m_Start.ry(),m_End.rx()-m_Start.rx(),m_End.ry()-m_End.ry()); for (int i=0;i<rect_array.size();i++) { rect_array[i]->Draw(painter); rect_array[i]->Draw(paintImage); } if (draw_status) { painter.drawRect(m_Start.rx(),m_Start.ry(),m_End.rx()-m_Start.rx(),m_End.ry()-m_Start.ry()); paintImage.drawRect(m_Start.rx(),m_Start.ry(),m_End.rx()-m_Start.rx(),m_End.ry()-m_Start.ry()); } painter.end(); update(); }
-
@joeQ
I‘ve tried to read four values from the 0.xml,xmin,ymin,xmax and ymax in "bndbox", and tp draw a rectangle with them.But it doesn't work. I've debuged only to find that I cannot get those values, though the reader can find "bndbox" well. There must have been something wrong in small details, could you please help me to figure out?The class ParseXml is used in ImageWidget.
//parsexml.h #pragma once #include <QXmlStreamReader> #include <QMessageBox> #include <QString> #include <QFile> class ParseXml { public: ParseXml(void); ParseXml(QString fileName); ~ParseXml(void); void ReadFile(const QString &fileName); void ReadAnnotation(); void ReadObject(); void ReadBndbox(); void Skip(); QPoint get_start_point(); QPoint get_end_point(); private: QXmlStreamReader reader; int m_xmin; int m_ymin; int m_xmax; int m_ymax; };
//parsexml.cpp #include "ParseXml.h" ParseXml::ParseXml(void) { } ParseXml::ParseXml(QString fileName) { ReadFile(fileName); } ParseXml::~ParseXml(void) { } void ParseXml::ReadFile(const QString &fileName) { QFile file(fileName); if (file.open(QIODevice::ReadOnly|QIODevice::Text)) { reader.setDevice(&file); while (!reader.atEnd()) { if (reader.isStartElement()) { if (reader.name()=="annotation") { ReadAnnotation(); } else { reader.raiseError(QObject::tr("Not a valid annotation file")); } } else { reader.readNext(); } } file.close(); } } void ParseXml::ReadAnnotation() { reader.readNext(); while(!reader.atEnd()) { if (reader.isEndElement()) { reader.readNext(); break; } if (reader.isStartElement()) { if (reader.name()=="object") { ReadObject(); } else { Skip(); } } else { reader.readNext(); } } } void ParseXml::ReadObject() { reader.readNext(); while (!reader.atEnd()) { if (reader.isEndElement()) { reader.readNext(); break; } if (reader.isStartElement()) { if (reader.name()=="bndbox") { ReadBndbox(); } else { Skip(); } } else { reader.readNext(); } } } void ParseXml::ReadBndbox() { int points[4]; for (int i=0;i<4;i++) { reader.readNext(); points[i] = reader.readElementText().toInt(); reader.readNext(); } m_xmin = points[0]; m_ymin = points[1]; m_xmax = points[2]; m_ymax = points[3]; } void ParseXml::Skip() { reader.readNext(); while(!reader.atEnd()) { if (reader.isEndElement()) { reader.readNext(); break; } if (reader.isStartElement()) { Skip(); } else { reader.readNext(); } } } QPoint ParseXml::get_start_point() { return QPoint(m_xmin,m_ymin); } QPoint ParseXml::get_end_point() { return QPoint(m_xmax,m_ymax); }
//imagewidget.h #ifndef IMAGEWIDGET_H #define IMAGEWIDGET_H #include <QWidget> #include <QImage> #include <vector> #include <QPainter> #include <QFileDialog> #include <QMouseEvent> #include <QMessageBox> #include <QXmlStreamReader> #include <QToolTip> #include "ui_imagewidget.h" #include "Rect.h" #include "ParseXml.h" using namespace std; class ImageWidget : public QWidget { Q_OBJECT public: ImageWidget(QWidget *parent = 0); ~ImageWidget(); public slots: void Open(); void Save(); void SaveAnnotation(); void ReadXml(); void SaveXml(); void Delete(); void paintEvent(QPaintEvent *); void mousePressEvent(QMouseEvent *event); void mouseMoveEvent(QMouseEvent *event); void mouseReleaseEvent(QMouseEvent *event); private: Ui::ImageWidget ui; QImage *ptr_image; QImage *ptr_save; QPoint m_Start; QPoint m_End; bool draw_status; bool load_status; vector<Rect*> rect_array; }; #endif // IMAGEWIDGET_H
//imagewidget.cpp #include "imagewidget.h" ImageWidget::ImageWidget(QWidget *parent) : QWidget(parent) { ui.setupUi(this); ptr_image = new QImage(); ptr_save = new QImage(); draw_status = false; load_status = false; setMouseTracking(true); } ImageWidget::~ImageWidget() { for (int i=0;i<rect_array.size();i++) { if (rect_array[i]) { delete rect_array[i]; rect_array[i] = NULL; } } } void ImageWidget::Open() { QString fileName = QFileDialog::getOpenFileName(this,tr("Read Image"),".",tr("Image(*.bmp *.png *.jpg)")); if (!fileName.isEmpty()) { ptr_image->load(fileName); load_status = true; } update(); } void ImageWidget::Save() { QString fileName = QFileDialog::getSaveFileName(this,tr("Save Image"),".",tr("Image(*.bpm *.png *.jpg)")); if (!fileName.isEmpty()) { ptr_save->save(fileName); } } void ImageWidget::SaveAnnotation() { } void ImageWidget::ReadXml() { QString fileName = QFileDialog::getOpenFileName(this,tr("Read Xml File"),".",tr("Xml(*.xml)")); ParseXml parsexml_(fileName); m_Start = parsexml_.get_start_point(); m_End = parsexml_.get_end_point(); } void ImageWidget::SaveXml() { QString fileName = QFileDialog::getSaveFileName(this,tr("Save Xml File"),".",tr("Xml(*.xml)")); } void ImageWidget::Delete() { if (!rect_array.empty()) { rect_array.pop_back(); } } void ImageWidget::mousePressEvent(QMouseEvent *event) { if (Qt::LeftButton==event->button()&&load_status) { draw_status = true; m_Start = m_End = event->pos(); } } void ImageWidget::mouseMoveEvent(QMouseEvent *event) { QToolTip::showText(event->globalPos(),QString::number( event->pos().x() ) + ", " +QString::number( event->pos().y() ),this, rect() ); QWidget::mouseMoveEvent(event); if (draw_status) { m_End = event->pos(); } } void ImageWidget::mouseReleaseEvent(QMouseEvent *event) { Rect *current_rect = NULL; current_rect = new Rect(m_Start,m_End); rect_array.push_back(current_rect); draw_status = false; } void ImageWidget::paintEvent(QPaintEvent *) { *ptr_save = *ptr_image; QPen pen; QPainter painter(this); QPainter paintImage(ptr_save); QRect image_rect(0,0,ptr_image->width(),ptr_image->height()); pen.setWidth(5); pen.setColor(Qt::red); painter.setPen(pen); paintImage.setPen(pen); painter.begin(this); paintImage.begin(ptr_save); painter.drawImage(image_rect,*ptr_image); painter.drawRect(m_Start.rx(),m_Start.ry(),m_End.rx()-m_Start.rx(),m_End.ry()-m_End.ry()); for (int i=0;i<rect_array.size();i++) { rect_array[i]->Draw(painter); rect_array[i]->Draw(paintImage); } if (draw_status) { painter.drawRect(m_Start.rx(),m_Start.ry(),m_End.rx()-m_Start.rx(),m_End.ry()-m_Start.ry()); paintImage.drawRect(m_Start.rx(),m_Start.ry(),m_End.rx()-m_Start.rx(),m_End.ry()-m_Start.ry()); } painter.end(); update(); }
wrote on 23 Jul 2017, 10:40 last edited by joeQHi, I found your error. below the code, you will know where are you wrong.
void ParseXml::ReadBndbox() { bool bOk; int points[4]; reader.readNext(); ///< Note: here, skip the '\n' some characters for (int i=0;i<4;i++) { bOk = false; reader.readNext(); points[i] = reader.readElementText().toInt(&bOk); if(!bOk){ qDebug("toInt data failed"); } reader.readNext(); } m_xmin = points[0]; m_ymin = points[1]; m_xmax = points[2]; m_ymax = points[3]; qDebug("%d %d %d %d\n",m_xmin,m_ymin,m_xmax,m_ymax); }
If i modified the xml file format, the code has error.
<bndbox><xmin>144</xmin> ///< not has '\n' ,will has error <ymin>485</ymin> <xmax>164</xmax> <ymax>515</ymax> </bndbox>
QXmlStream* => io stream
-
@joeQ
I‘ve tried to read four values from the 0.xml,xmin,ymin,xmax and ymax in "bndbox", and tp draw a rectangle with them.But it doesn't work. I've debuged only to find that I cannot get those values, though the reader can find "bndbox" well. There must have been something wrong in small details, could you please help me to figure out?The class ParseXml is used in ImageWidget.
//parsexml.h #pragma once #include <QXmlStreamReader> #include <QMessageBox> #include <QString> #include <QFile> class ParseXml { public: ParseXml(void); ParseXml(QString fileName); ~ParseXml(void); void ReadFile(const QString &fileName); void ReadAnnotation(); void ReadObject(); void ReadBndbox(); void Skip(); QPoint get_start_point(); QPoint get_end_point(); private: QXmlStreamReader reader; int m_xmin; int m_ymin; int m_xmax; int m_ymax; };
//parsexml.cpp #include "ParseXml.h" ParseXml::ParseXml(void) { } ParseXml::ParseXml(QString fileName) { ReadFile(fileName); } ParseXml::~ParseXml(void) { } void ParseXml::ReadFile(const QString &fileName) { QFile file(fileName); if (file.open(QIODevice::ReadOnly|QIODevice::Text)) { reader.setDevice(&file); while (!reader.atEnd()) { if (reader.isStartElement()) { if (reader.name()=="annotation") { ReadAnnotation(); } else { reader.raiseError(QObject::tr("Not a valid annotation file")); } } else { reader.readNext(); } } file.close(); } } void ParseXml::ReadAnnotation() { reader.readNext(); while(!reader.atEnd()) { if (reader.isEndElement()) { reader.readNext(); break; } if (reader.isStartElement()) { if (reader.name()=="object") { ReadObject(); } else { Skip(); } } else { reader.readNext(); } } } void ParseXml::ReadObject() { reader.readNext(); while (!reader.atEnd()) { if (reader.isEndElement()) { reader.readNext(); break; } if (reader.isStartElement()) { if (reader.name()=="bndbox") { ReadBndbox(); } else { Skip(); } } else { reader.readNext(); } } } void ParseXml::ReadBndbox() { int points[4]; for (int i=0;i<4;i++) { reader.readNext(); points[i] = reader.readElementText().toInt(); reader.readNext(); } m_xmin = points[0]; m_ymin = points[1]; m_xmax = points[2]; m_ymax = points[3]; } void ParseXml::Skip() { reader.readNext(); while(!reader.atEnd()) { if (reader.isEndElement()) { reader.readNext(); break; } if (reader.isStartElement()) { Skip(); } else { reader.readNext(); } } } QPoint ParseXml::get_start_point() { return QPoint(m_xmin,m_ymin); } QPoint ParseXml::get_end_point() { return QPoint(m_xmax,m_ymax); }
//imagewidget.h #ifndef IMAGEWIDGET_H #define IMAGEWIDGET_H #include <QWidget> #include <QImage> #include <vector> #include <QPainter> #include <QFileDialog> #include <QMouseEvent> #include <QMessageBox> #include <QXmlStreamReader> #include <QToolTip> #include "ui_imagewidget.h" #include "Rect.h" #include "ParseXml.h" using namespace std; class ImageWidget : public QWidget { Q_OBJECT public: ImageWidget(QWidget *parent = 0); ~ImageWidget(); public slots: void Open(); void Save(); void SaveAnnotation(); void ReadXml(); void SaveXml(); void Delete(); void paintEvent(QPaintEvent *); void mousePressEvent(QMouseEvent *event); void mouseMoveEvent(QMouseEvent *event); void mouseReleaseEvent(QMouseEvent *event); private: Ui::ImageWidget ui; QImage *ptr_image; QImage *ptr_save; QPoint m_Start; QPoint m_End; bool draw_status; bool load_status; vector<Rect*> rect_array; }; #endif // IMAGEWIDGET_H
//imagewidget.cpp #include "imagewidget.h" ImageWidget::ImageWidget(QWidget *parent) : QWidget(parent) { ui.setupUi(this); ptr_image = new QImage(); ptr_save = new QImage(); draw_status = false; load_status = false; setMouseTracking(true); } ImageWidget::~ImageWidget() { for (int i=0;i<rect_array.size();i++) { if (rect_array[i]) { delete rect_array[i]; rect_array[i] = NULL; } } } void ImageWidget::Open() { QString fileName = QFileDialog::getOpenFileName(this,tr("Read Image"),".",tr("Image(*.bmp *.png *.jpg)")); if (!fileName.isEmpty()) { ptr_image->load(fileName); load_status = true; } update(); } void ImageWidget::Save() { QString fileName = QFileDialog::getSaveFileName(this,tr("Save Image"),".",tr("Image(*.bpm *.png *.jpg)")); if (!fileName.isEmpty()) { ptr_save->save(fileName); } } void ImageWidget::SaveAnnotation() { } void ImageWidget::ReadXml() { QString fileName = QFileDialog::getOpenFileName(this,tr("Read Xml File"),".",tr("Xml(*.xml)")); ParseXml parsexml_(fileName); m_Start = parsexml_.get_start_point(); m_End = parsexml_.get_end_point(); } void ImageWidget::SaveXml() { QString fileName = QFileDialog::getSaveFileName(this,tr("Save Xml File"),".",tr("Xml(*.xml)")); } void ImageWidget::Delete() { if (!rect_array.empty()) { rect_array.pop_back(); } } void ImageWidget::mousePressEvent(QMouseEvent *event) { if (Qt::LeftButton==event->button()&&load_status) { draw_status = true; m_Start = m_End = event->pos(); } } void ImageWidget::mouseMoveEvent(QMouseEvent *event) { QToolTip::showText(event->globalPos(),QString::number( event->pos().x() ) + ", " +QString::number( event->pos().y() ),this, rect() ); QWidget::mouseMoveEvent(event); if (draw_status) { m_End = event->pos(); } } void ImageWidget::mouseReleaseEvent(QMouseEvent *event) { Rect *current_rect = NULL; current_rect = new Rect(m_Start,m_End); rect_array.push_back(current_rect); draw_status = false; } void ImageWidget::paintEvent(QPaintEvent *) { *ptr_save = *ptr_image; QPen pen; QPainter painter(this); QPainter paintImage(ptr_save); QRect image_rect(0,0,ptr_image->width(),ptr_image->height()); pen.setWidth(5); pen.setColor(Qt::red); painter.setPen(pen); paintImage.setPen(pen); painter.begin(this); paintImage.begin(ptr_save); painter.drawImage(image_rect,*ptr_image); painter.drawRect(m_Start.rx(),m_Start.ry(),m_End.rx()-m_Start.rx(),m_End.ry()-m_End.ry()); for (int i=0;i<rect_array.size();i++) { rect_array[i]->Draw(painter); rect_array[i]->Draw(paintImage); } if (draw_status) { painter.drawRect(m_Start.rx(),m_Start.ry(),m_End.rx()-m_Start.rx(),m_End.ry()-m_Start.ry()); paintImage.drawRect(m_Start.rx(),m_Start.ry(),m_End.rx()-m_Start.rx(),m_End.ry()-m_Start.ry()); } painter.end(); update(); }
wrote on 23 Jul 2017, 11:25 last edited by joeQ@Geng.Y Hi, friend.
I write the code in my way. it maybe safer than your code.
void ParseXml::ReadBndbox() { if(reader.name() == "bndbox"){ reader.readNext(); }else{ /// maybe return false at here. } while(!reader.isStartElement()){ reader.readNext(); } m_xmin = ReadItemPos("xmin"); m_ymin = ReadItemPos("ymin"); m_xmax = ReadItemPos("xmax"); m_ymax = ReadItemPos("ymax"); Q_ASSERT(m_xmin >= 0 && m_ymin >= 0); Q_ASSERT(m_xmax >= 0 && m_ymax >= 0); qDebug("%d %d %d %d",m_xmin,m_ymin,m_xmax,m_ymax); } int ParseXml::ReadItemPos(QString itemName) { int nVal = -1; bool bOk; while(!reader.isStartElement()){ reader.readNext(); } if(reader.name() == itemName){ nVal = reader.readElementText().toInt(&bOk); Q_ASSERT(bOk == true); reader.readNext(); } return nVal; }
-
wrote on 23 Jul 2017, 12:17 last edited by
-
Thank you very much, I'm still puzzled about the "reader.readNext()"
And I can't find the output of qDebug. It should be in the output window, right? But my output window is constantly emitting such kind of informations.
wrote on 24 Jul 2017, 00:36 last edited by joeQok,let's to see the function
readNext
.TokenType QXmlStreamReader::readNext()
Reads the next token and returns its type.1. what is the next token ?
you can print the token to string.
QString QXmlStreamReader::tokenString() const
Returns the reader's current token as string.2. what is the type?
QXmlStreamReader::NoToken
QXmlStreamReader::Invalid
QXmlStreamReader::StartDocument
QXmlStreamReader::EndDocument
QXmlStreamReader::StartElement
QXmlStreamReader::EndElement
QXmlStreamReader::Characters
QXmlStreamReader::Comment
QXmlStreamReader::DTD
QXmlStreamReader::EntityReference
QXmlStreamReader::ProcessingInstructionyou should to check every type whether is you want, after you call
readNext
.from the code,
readNext
returnCharacters
token type.QXmlStreamReader::Characters The reader reports characters in text(). If the characters are all white-space, isWhitespace() returns true. If the characters stem from a CDATA section, isCDATA() returns true.
3. How to understanding xml tokens?
go to here
-
wrote on 24 Jul 2017, 01:51 last edited by
Thank you very much!
1/9