PDA

View Full Version : How to parse this xml file?



Gokulnathvc
10th September 2012, 07:53
How to parse this xml file and get the folder name as release\sf\p1 and file name as setg and metg.??


<package version="1.0">
<tools>
<charlie>
<minversion>3.01.05</minversion>
</charlie>
<tango>
<minversion>4.0.4</minversion>
</tango>
</tools>
<folder name="release">
<folder name="sf">
<folder name="p1">
<file name="setg">
<version>1.4.1.2</version>
<offset>0</offset>
<attribute type="encrypted">1</attribute>
</file>
<file name="metg">
<version>1.4.1.2</version>
<offset>0</offset>
<attribute type="encrypted">1</attribute>
</file>
</folder>
</folder>
</folder>
</package>

ChrisW67
10th September 2012, 08:19
Using the facilities of the QtXml or QtXmlPatterns module or QXmlStreamReader.

How about you tell us what you have tried?

Gokulnathvc
10th September 2012, 08:24
I have tried with QDocDocument and I am always getting values as 1.4.1.2011.4.1.201?


QList< QMap<QString,QString> > Package;

/* QDomDocument takes any QIODevice. as well as QString buffer*/
QDomDocument doc("mydocument");
if (!doc.setContent(xmlFile))
{
return;
}

//Get the root element
QDomElement docElem = doc.documentElement();

// you could check the root tag name here if it matters
QString rootTag = docElem.tagName(); // == package
QString fll = docElem.text();

// get the node's interested in, this time only caring about person's
QDomNodeList nodeList = docElem.elementsByTagName("folder");

//Check each node one by one.
for(int ii = 0;ii < nodeList.count(); ii++)
{
QMap<QString, QString> firmwarefolder;

// get the current one as QDomElement
QDomElement el = nodeList.at(ii).toElement();

firmwarefolder["folder"] = el.attribute("folder"); // get and set the attribute ID
firmwarefolder["file"] = el.attribute("file");

//get all data for the element, by looping through all child elements
QDomNode pEntries = el.firstChild();
while(!pEntries.isNull()) {
QDomElement peData = pEntries.toElement();
QString tagNam = peData.tagName();

if(tagNam == "folder") { /* We've found first name. */
firmwarefolder["file"] = el.text();
}else if(tagNam == "file") { /* We've found surname. */
firmwarefolder["file"] = peData.text();
}

pEntries = pEntries.nextSibling();
}

Package.append(firmwarefolder);
}


I have added these codes. But am not getting the folder name and file name.. Whats wrong with this?

wysota
10th September 2012, 09:08
The attribute you are looking for is called "name" and not "folder".

Gokulnathvc
11th September 2012, 05:51
I have tried with that and got the values, but still it is showing me different values not the output what i have mentioned above


<folder name="release">
<folder name="sf">
<folder name="ppro">
<file name="22345">
<version>1.4.1.2</version>
<offset>0</offset>
<attribute type="encrypted">1</attribute>
</file>
<file name="22566">
<version>1.4.1.2</version>
<offset>0</offset>
<attribute type="encrypted">1</attribute>
</file>
</folder>
</folder>
</folder>
<folder name="release">
<folder name="bios">
<file name="1184">
<version>1.4.1.2</version>
<offset>0</offset>
<attribute type="encrypted">1</attribute>
</file>
<file name="1084">
<version>1.4.1.2</version>
<offset>0</offset>
<attribute type="encrypted">1</attribute>
</file>
</folder>
</folder>

How to get the values in first loop as folder = releasesfppro and file = 2234522566 and in second loop as folder = releasebios file = 11841084???

ChrisW67
11th September 2012, 06:32
You are getting the text of the <folder> and <file> elements that you are asking for at lines 38 and 40. If you want the value of the name attribute of these elements then you should ask for that.

Gokulnathvc
11th September 2012, 06:45
I have updated the code and edited the values in the previous comment. Could you look at that?

wysota
11th September 2012, 07:04
Do you understand the difference between XML attribute value and XML tag text?

Gokulnathvc
11th September 2012, 07:06
I am new to XML programming. Could you see my updated code and give me suggestion and a solution?


QDomNodeList nodeList = docElem.elementsByTagName("folder");
for(int k = 0;k < nodeList.count(); k++)
{
QDomElement el = nodeList.at(k).toElement();
firmFolder += el.attribute("name");
firmFolder += "/";
}

nodeList = docElem.elementsByTagName("file");
for(int l = 0;j < nodeList.count(); l++)
{
QDomElement el = nodeList.at(l).toElement();
firmFiles += el.attribute("name");
firmFiles += " ";
}



I have added these codes. but am getting folder as release/sf/ppro/release/bios and file as 223452256611841084?
But i should get this as release/sf/ppro/ and file 2234522566 for first loop.. and release/bios and file 11841084 for the second loop.. How to get this..

ChrisW67
11th September 2012, 07:18
I am new to XML programming. Could you see my updated code and give me suggestion and a solution?
The code has not been changed as far as I can see. There's still the obvious errors at line 38/40

I have already told you what you need to query to retrieve the folder/file name from the <folder>/<file> element, and you are already using the relevant function. Wysota has already given you the name of the attribute you want. If you explain which part you do not understand we can help

Gokulnathvc
11th September 2012, 07:21
Kindly check the updated code..
QDomNodeList nodeList = docElem.elementsByTagName("folder");
for(int k = 0;k < nodeList.count(); k++)
{
QDomElement el = nodeList.at(k).toElement();
firmFolder += el.attribute("name");
firmFolder += "/";
}

nodeList = docElem.elementsByTagName("file");
for(int l = 0;j < nodeList.count(); l++)
{
QDomElement el = nodeList.at(l).toElement();
firmFiles += el.attribute("name");
firmFiles += " ";
}

wysota
11th September 2012, 07:44
In your code you are destroying the xml structure, instead using a flat list of tags. You need to recursively walk down the DOM tree.

Gokulnathvc
11th September 2012, 07:45
Could you modify my code.. how it should be like?

wysota
11th September 2012, 07:49
Find the top-most "folder" tag, then read its attribute, ask for the first child tag, if it is folder or file then process it, otherwise ignore it. Then proceed to the next sibling and keep doing the same until you reach the end of hierarchy.

QDomNode::firstChild(), QDomNode::firstChildElement(), QDomNode::nextSibling(), QDomNode::nextSiblingElements() and QDomNode::toElement() are your friends.

There is also a simple example in QDomElement docs.

Gokulnathvc
11th September 2012, 08:10
How to find the top most tag and process as i mentioned in the output in the previous comment. I am getting the same output..


for(int k = 0; !n.isNull(); n = n.nextSibling(), k++)
{
QDomNodeList nodeList = docElem.elementsByTagName("folder");
QDomElement el = nodeList.at(k).toElement();
firmFolder += el.attribute("name");
firmFolder += "/";

nodeList = docElem.elementsByTagName("file");
el = nodeList.at(k).toElement();
firmFiles += el.attribute("name");
firmFiles += " ";


}


I have added this code.. but am not getting the required output as mentioned.. Could you help me? I am getting releasesfppro and file as 22345 22566 1184.. and it comes out of the loop.. i cant see other values.

wysota
11th September 2012, 08:45
You are still processing a flat list of tags. And you'll be doing that all the time until you get rid of "elementsByTagName" which gives you a flat list of elements. Please see the example in QDomElement.

ChrisW67
11th September 2012, 08:51
You will continue to get the same output if you continue to do the same things... so try something different. Wysota's list of documentation does not include elementsByTagName() because it gives you all the folder elements descended from a parent... and you do not want them all at once.

If you want the first element perhaps a function with the word "first" in its name would be a good place to start.

Gokulnathvc
11th September 2012, 08:53
Could you edit my code and give a sample code. How I should process it?

Gokulnathvc
11th September 2012, 12:38
for ( node = docElem.firstChild(); !node.isNull();node = node.nextSibling()) {

while(node.toElement().tagName() == "folder")
{
firmFolder += node.toElement().attribute("name");
firmFolder += "/";
node = node.firstChild();

}
while(node.toElement().tagName() == "file")
{
firmFiles += node.toElement().attribute("name");
firmFiles += " ";
node = node.nextSibling();

}

}

I have added this code and it worked for the current structure. However it stops after one execution. I couldnt get the second values of folder and file also. third values of folder and file.

wysota
11th September 2012, 14:46
Analyze your own code. Take a piece of paper, a pencil and go step by step through your algorithm and you'll find out why it stops after finding the first file.

Gokulnathvc
12th September 2012, 08:35
I have found the solution>>. Thanks for your help.

for ( node = docElem.firstChild();!node.isNull();node = node.nextSibling()) {

while(node.toElement().tagName() == "folder")
{
firmFolder += node.toElement().attribute("name");
firmFolder += "/";
node = node.firstChild();
}
while(node.toElement().tagName() == "file")
{
firmFiles += node.toElement().attribute("name");
firmFiles += " ";
saveNode = node;
node = node.nextSibling();
}

//node = docElem.firstChild();
node = saveNode.parentNode();

while(node.parentNode().toElement().tagName() != "package"){
node = node.parentNode();
}
}

wysota
12th September 2012, 08:51
That's a really bad solution.

Here is a better one:

Implement the following function called "getPath"
1. Go to first child element with tag "folder"
2. If there is no such tag, go to first child element with tag "file", otherwise skip to step 6
3. If there is no such tag, return an empty list
4. Add the name of the file to a list
5. Go to next sibling of the tag that is also tagged "file", add it to the list and keep doing that until you run out of "file" tags. Then return a list of files found.
6. Call getPath on the folder tag.
7. For each string returned by getPath, prepend it with the folder name just found and a directory separator
8. Repeat for all sibling "folder" tags
9. Return a list of found entries.

If you call getPath on the parent node of the "folder" nodes, you'll get a complete list of entries in the package.

Gokulnathvc
12th September 2012, 11:13
Could you modify my code and describe how it should be?

wysota
12th September 2012, 11:33
No, I would have to discard your code and write a new one from scratch. And if I wanted to, I would have already done that. Learn your lesson and do it yourself.