I had some problem with parsing xml document with french words.
For example pĂȘche
After parsing i have this: "p\xc3\xaache" instead of "pĂȘche"
Here is my code:
for(pugi::xml_node child = parent.first_child(); child; child = child.next_sibling()){
std::string desc = child.child_value("word");
}
Any suggestions?
Tnx.
Related
Consider the following code
CXmlDomNodeList oNodeList = m_oInputXmlData.pXmlDomRecvd->GetElementsByTagName("check_info");
for (CXmlDomNode oCheckNode = oNodeList.First(); oCheckNode; oCheckNode = oNodeList.Next())
{
i64CheckId = _atoi64(oCheckNode.GetChildNodeText("check_id"));
// do some stuff
}
When i try to read all the elements in XML collection i read only the first number in the tag check_id, and skips the rest .. i'm trying to deal with this problem for 2 days now and i need your help.
Here is the XML sample
<?xml version="1.0" encoding="windows-1251"?>
<iserver_request>
<command>1603</command>
<session>175395b931bf265ef9b6632fea48b060</session>
<check_info>
<check_id>166123</check_id>
<check_id>16123</check_id>
<check_id>1266</check_id>
<check_id>1636</check_id>
<check_id>1646</check_id>
<check_id>1656</check_id>
</check_info>
</iserver_request>
Your help would be highly appreciated.
Okay so i fixed this my self and i am posting the answer in case somebody has the same problem
CXmlDomNodeList oNodeList = m_oInputXmlData.pXmlDomRecvd->GetElementsByTagName("check_id");
for (CXmlDomNode oCheckNode = oNodeList.First(); oCheckNode; oCheckNode = oNodeList.Next())
{
i64CheckId = _atoi64(oCheckNode.GetText());
//do stuff
}
That's how i got all the element in the tag check_id.
This question already has an answer here:
Reading an XML file using QXmlStreamReader
(1 answer)
Closed 6 years ago.
I have xml file in my local machine. The xml file format is like:
<string>
<Data>
<Name>Sanket</Name>
<Number>0987654321</Number>
<Address>India</Address>
</Data>
<Data>
<Name>Rahul</Name>
<Number>0987654321</Number>
<Address>Maharashtra</Address>
</Data>
</string>
I want to convert this XML file data into String format. Like:
Sanket 0987654321 India
Rahul 0987654321 Maharashtra
What is the easiest way to convert this data in QT using c++.
I am new in that, so please can anyone suggest me some sample code for this?
Thank you in advance.
I tried following code, but that not work for me:
void parseFile()
{
QList<QList<QString> > dataSet;
QString lastError = "";
QFile inFile("test.xml");
if (inFile.open(QIODevice::ReadOnly))
{
QTextStream fread(&inFile);
long totalSize = inFile.size();
QString line;
while(!fread.atEnd())
{
line = fread.readLine();
QList<QString> record = line.split(QString::KeepEmptyParts);
dataSet.append(record);
}
qDebug()<<dataSet;
}else{
lastError = "Could not open "+test.xml+" for reading";
}
}
You could parse the xml elements firstly via QXmlStreamReader and then you can assemble the xml elements into the string how you want.
The problem of you Code is that you only process the text Lines without any xml-syntax processed by the xml class.
You should look at the QtXML classes for which Florent Uguet provided some links.
However I modified the example found here to do what you want (It does that exact thing for your exact input):
#include <QDomDocument>
#include <QFile>
#include <iostream>
#include <QDomNodeList>
int main()
{
QDomDocument doc("mydocument");
QFile file("test.xml");
if (!file.open(QIODevice::ReadOnly))
return 1;
if (!doc.setContent(&file)) {
file.close();
return 1;
}
file.close();
const auto stringTags = doc.elementsByTagName("string");
for(int stringsI = 0; stringsI < stringTags.size(); ++stringsI){
QDomNode stringTag = stringTags.at(stringsI);
for(QDomNode dataTag = stringTag.firstChildElement("Data"); !dataTag.isNull(); dataTag = dataTag.nextSiblingElement("Data")){
for(QDomNode innerTag = dataTag.firstChild(); !innerTag.isNull(); innerTag = innerTag.nextSibling()){
auto val = innerTag.toElement().text();
std::cout << val.toStdString() << " ";
}
std::cout << std::endl;
}
}
return 0;
}
I build it with QtCreator using qmake. For this you should know that you need to put QT += xml in your *.pro file.
Already asked (and with code) : Reading an XML file using QXmlStreamReader
Qt provides a set of classes for handling XML :
http://doc.qt.io/qt-5.7/qtxml-index.html
http://doc.qt.io/qt-5.7/qxmlstreamreader.html
http://doc.qt.io/qt-5.7/qxmlstreamwriter.html
Old C++ classes (not maintained)
http://doc.qt.io/qt-5/qtxml-module.html
Once you have parsed your file using these, you can usually read the individual nodes' inner text or attributes.
I'm using RapidXML to parse XML files and read nodes content but I don't want to read values inside a node, I need to read the content of specific XML nodes "as XML" not as parsed values.
Example :
<node1>
<a_lot_of_xml>
< .... >
</a_lot_of_xml>
</node1>
I need to get the content of node1 as :
<a_lot_of_xml>
< .... >
</a_lot_of_xml>
What I tired :
I tried something but its not really good in my opinion, its about to put in node1, the path of an other xml file to read, I did like this :
<file1ToRead>MyFile.xml</file1ToRead>
And then my c++ code is the following :
ifstream file(FileToRead);
stringstream buffer; buffer << file.rdbuf();
But the problem is users will have a lot of XML files to maintain and I just want to use one xml file.
I think "a lot of XML files" is a better way, so you have a directory of all xml files, you can read the xml file when you need it, good for performance.
Back to the problem, can use the rapidxml::print function to get the xml format.
bool test_analyze_xml(const std::string& xml_path)
{
try
{
rapidxml::file<> f_doc(xml_path.c_str());
rapidxml::xml_document<> xml_doc;
xml_doc.parse<0>(const_cast<char*>(f_doc.data()));
rapidxml::xml_node<>* node_1 = xml_doc.first_node("node1");
if(node_1 == NULL)
{
return false;
}
rapidxml::xml_node<>* plain_txt = node_1->first_node("a_lot_of_xml");
if (plain_txt == NULL)
{
return false;
}
std::string xml_data;
rapidxml::print(std::back_inserter(xml_data), *plain_txt, rapidxml::print_no_indenting); //the xml_data is XML format.
}
catch (...)
{
return false;
}
return true;
}
I'm unfamiliar with rapidxml, but I have done this with tinyxml2. The trick is to read out node1 and then create a new XMLDoc (using tinyxml2 terms here) that contains everything inside of node1. From there, you can use their XMLPrinter class to convert your new XMLDoc (containing everything in node1) to a string.
tinyxml2 is a free download.
My test.xml like this:
<?xml version="1.0"?>
<!DOCTYPE PLAY SYSTEM "play.dtd">
<data>
<CurrentLevel>5</CurrentLevel>
<BestScoreLV1>1</BestScoreLV1>
<BestScoreLV2>2</BestScoreLV2>
</data>
<dict/>
My Code here:
std::string fullPath = CCFileUtils::sharedFileUtils()->fullPathFromRelativePath("text.xml");
tinyxml2::XMLDocument doc;
doc.LoadFile(fullPath.c_str());
tinyxml2::XMLElement* ele = doc.FirstChildElement("data")->FirstChildElement("BestScoreLV2")->ToElement();
ele->SetAttribute("value", 10);
doc.SaveFile(fullPath.c_str());
const char* title1 = doc.FirstChildElement("data")->FirstChildElement("BestScoreLV2")->GetText();
int level1 = atoi(title1);
CCLOG("result is: %d",level1);
But value of BestScoreLV2 when output is also 2. How can I change and write data to XML?
In TinyXML2 text is represented by XMLText class which is child of XMLNode class.
XMLNode have methods Value() and SetValue() which have different meanings for different XML nodes.
For text nodes Value() read node's text and SetValue() write it.
So you need code like this:
tinyxml2::XMLNode* value = doc.FirstChildElement("data")->
FirstChildElement("BestScoreLV2")->FirstChild();
value->SetValue("10");
The first child of BestScoreLV2 element is XMLText with value 2. You change this value to 10 by calling SetValue(10).
How do I parse the following in TinyXML:
<multi_path literal="not_measured"/>
I am able to easily parse the below line:
<hello>1234</hello>
The problem is that the first statement is not getting parsed the normal way. Please suggest how to go about this.
Not 100% sure what youre question is asking but here is a basic format too loop through XML files using tinyXML:
/*XML format typically goes like this:
<Value atribute = 'attributeName' >
Text
</value>
*/
TiXmlDocument doc("document.xml");
bool loadOkay = doc.LoadFile(); // Error checking in case file is missing
if(loadOkay)
{
TiXmlElement *pRoot = doc.RootElement();
TiXmlElement *element = pRoot->FirstChildElement();
while(element)
{
string value = firstChild->Value(); //Gets the Value
string attribute = firstChild->Attribute("attribute"); //Gets the attribute
string text = firstChild->GetText(); //Gets the text
element = element->NextSiblingElement();
}
}
else
{
//Error conditions
}