Reading XML file
-
Hi all,
In my application, I need to implement options to
save
,modify
,remove
xml files.
I cansave
the data (getting information with atab widget
), as follows:void StageTwoNew::on_pushButton_clicked() { QString filename = ui->lineEdit_3->text(); QString path = QCoreApplication::applicationDirPath()+"/data/"+filename+".xml"; QFile file(path); if(!file.open(QFile::WriteOnly | QFile::Text)) { qDebug () << "Error saving XML file...."; file.close(); return; } QDomDocument xml("dataentry"); QDomElement root = xml.createElement("subject details"); root.setAttribute("catagory","run session"); xml.appendChild(root); QDomElement tagName = xml.createElement("Name"); root.appendChild(tagName); QDomText textName = xml.createTextNode(ui->lineEdit->text()); tagName.appendChild(textName); QDomElement tagSname = xml.createElement("Surname"); root.appendChild(tagSname); QDomText textSname = xml.createTextNode(ui->lineEdit_2->text()); tagSname.appendChild(textSname); QDomElement tagPID = xml.createElement("Subject ID"); root.appendChild(tagPID); QDomText textPID = xml.createTextNode(ui->lineEdit_3->text()); tagPID.appendChild(textPID); QDomElement tagDateTime = xml.createElement("Date"); root.appendChild(tagDateTime); QDomText textDateTime = xml.createTextNode(ui->dateTimeEdit->text()); tagDateTime.appendChild(textDateTime); QDomElement tagNote = xml.createElement("Extra Note"); root.appendChild(tagNote); QDomText textNote = xml.createTextNode(ui->textEdit->toPlainText()); tagNote.appendChild(textNote); QTextStream output(&file); output << xml.toString(); file.close(); }
I now want to implement
modify
part. Basically I need to open the xml file and to present content to the sametab widget
for user to modify and save it.I did this when clicked
modify
button in the form:void MainWindow::on_pushButton_2_clicked() { QDomDocument document; QString path = QCoreApplication::applicationDirPath()+"/data/"; QString filename = QFileDialog::getOpenFileName(this, ("Open file"), path, "Xml files (*.xml)"); // Open a file for reading QFile file(filename); if(!file.open(QIODevice::ReadOnly | QIODevice::Text)) { qDebug() << "Failed to open the file for reading."; } else { // loading if(!document.setContent(&file)) { qDebug() << "Failed to load the file for reading."; } file.close(); } // Getting root element QDomElement root = document.firstChildElement(); // retrievelements(QDomElement root, QString tag, QString att) retrievElements(root, "Dorm", "Name"); qDebug() << "Reading finished"; }
Here the file is opened OK but I can't load the file for reading. What I'm doing wrong here?
I need to load the content of xml file and present into thetab widget
for the user to edit.Any suggestion will be helpful. Thanks in advance
-
@russjohn834
I assume you mean it fails ondocument.setContent(&file)
? So use the https://doc.qt.io/qt-5/qdomdocument.html#setContent-6 overload to obtain all the error information via the optional parameters? -
@JonB Thank you. Could you please show me how to use optional parameters of
setContent
to get error information? -
@russjohn834 Please read documentation, this is nothing special:
QString errorMsg; int errorLine; int errorColumn; if(!document.setContent(&file, &errorMessage, &errorLine, &errorColumn))
-
@russjohn834
Well I'm not a C++-er, I thought you'd know from the doc page syntax, you're already managing to pass&file
forQIODevice *dev
.QDomDocument::setContent(QIODevice *dev, QString *errorMsg = nullptr, int *errorLine = nullptr, int *errorColumn = nullptr)
so something like
QFile file; QString errorMsg; int errorLine, errorColumn; if (!document.setContent(&file, &errorMsg, &errorLine, &errorColumn)) { qDebug () << errorMsg << errorLine << errorColumn }
and then look at your XML in that light.
-
I'm getting following error (AND error line and column) while loading the xml file:
"unexpected character" 2 18
I'm trying to read xml file, which looks like this:
<!DOCTYPE detailsentry> <subject details catagory="run session"> <Name>Rob</Name> <Surname>John</Surname> <Patient ID>PID12HL</Patient ID> <Date>06/11/2019 20:00</Date> <Clinician Note>Some notes to test this section</Clinician Note> </subject details>
Any thoughts where I'm getting wrong!?
-
@russjohn834
Yes, on line #2 at character #18! That's what the error info is telling you!<subject details catagory="run session">
Count to character #18. What is that space in
details catagory
? (BTW, if you care,category
is the correct spelling.) You can't have a space there. Nor for that matter in your<Patient ID>
and others. Where did you get this XML from? You need to test your code with well-formed XML before you do anything. -
Thank you @JonB !
Now I can load the xml file:
<!DOCTYPE detailsentry> <subject_details> <Name>Pete</Name> <Surname>Batty</Surname> <Patient_ID>GH34TRM</Patient_ID> <Date>06/11/2019 16:00</Date> <Clinician_Note>test note to display</Clinician_Note> </subject_details>
I'm trying to parse data (
Name
,Surname
,Patient_ID
,Date
andClinician_Note
) from this xml file.domDocument.setContent(&file); QDomElement topElement = domDocument.documentElement(); QDomNode domNode = topElement.firstChild(); while (!domNode.isNull()) { QDomElement domElement = domNode.toElement(); if (!domElement.isNull()) { qDebug()<<"Tag name"<<topElement.tagName(); } domNode = domNode.nextSibling(); }
This does output
Tag name "subject_details"
for 5 times. How can I parse content in each line? -
@russjohn834 said in Reading XML file:
qDebug()<<"Tag name"<<topElement.tagName();
This does output Tag name
"subject_details"
for 5 times. How can I parse content in each line?Now come on :) Nicely, if it prints the same thing 5 times, look at what it's printing!
topElement
doesn't change in the loop, does it? ButdomElement
does ... -
This post is deleted!
-
@russjohn834
I'm not going to answer every question, you have to do some work yourself! Did you try looking at the documentation forQDomElement
since that is what you are asking about? Did you like the look of https://doc.qt.io/qt-5/qdomelement.html#text? -
Thanks @JonB . Sorry I just found what I need. I can directly parse content of each
domElement
by followingQDomElement topElement = domDocument.documentElement(); topElement.elementsByTagName("Name").at(0).firstChild().nodeValue(); topElement.elementsByTagName("Surname").at(0).firstChild().nodeValue(); ....
-
@russjohn834
You can, but why change over to that way of doing it when you are already usingQDomElement
calls elsewhere which is more convenient? -
I was too much confused about different terminologies of xml and methods of
QDomDocument
. I'm fiddling with my very basic knowledge to parse data from xml :) Yes, the documentation makes it more clear.@JonB said in Reading XML file:
@russjohn834
You can, but why change over to that way of doing it when you are already usingQDomElement
calls elsewhere which is more convenient?Did not get your point. You recommend
topElement.elementsByTagName("Name").at(0).firstChild().nodeValue();
than using loop to fetch content? -
@russjohn834
My thought/inclination is to make the reading code look like the code you already show, which usesQDomElement
. So something like:QDomNode domElement = topElement.elementsByTagName("Name").at(0).firstChild(); QDomElement domElement = domNode.toElement(); if (!domElement.isNull()) return domElement.text();
It's just a matter of style. If I access things in one place via
QDomElement
calls, with its dedicatedtext()
method, I prefer not to go viaQDomNode
and itsnodeValue()
method somewhere else. Just makes code easier to search/maintain/debug if you keep consistency where possible.