Format XML file in c++ or Qt
Asked Answered
C

5

8

I have an XML file where outputs are not getting formatted. That means all the outputs are in a single line but I want to break it tag by tag.

For e.g. -

<?xml version="1.0" encoding="UTF-8" standalone="no" ?><Analyser>   <JointDetails>              <Details><StdThickness> T </StdThickness><Thickness_num> 0.032 </Thickness_num></Details>   </JointDetails></Analyser>

But i want to do it like this ::

<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<Analyser>  
 <JointDetails>
   <Details>
<StdThickness> T </StdThickness>
<Thickness_num> 0.032 </Thickness_num>
</Details> 
  </JointDetails>
</Analyser>

Please don't suggest to do it while writing the XML file because this XML file is already there but now I have to format it as mentioned above.

Cort answered 19/12, 2012 at 6:30 Comment(1)
Read the XML with TinyXML, print it out with TiXMLPrinter, which defaults to pretty printing.Lifeguard
C
3
void format(void)
{
    QDomDocument input;

    QFile inFile("D:/input.xml");
    QFile outFile("D:/output.xml");

    inFile.open(inFile.Text | inFile.ReadOnly);
    outFile.open(outFile.Text | outFile.WriteOnly);

    input.setContent(&inFile);

    QDomDocument output(input);
    QTextStream stream(&outFile);
    output.save(stream, 2);
}
Cort answered 21/12, 2012 at 5:47 Comment(0)
D
10

Using a QXmlStreamReader and QXmlStreamWriter should do what you want. QXmlStreamWriter::setAutoFormatting(true) will format the XML on different lines and use the correct indentation. With QXmlStreamReader::isWhitespace() you can filter out superfluous whitespace between tags.

QString xmlIn = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\" ?>"
                "<Analyser><JointDetails>              <Details><StdThickness>"
                " T </StdThickness><Thickness_num> 0.032 </Thickness_num>"
                "</Details>   </JointDetails></Analyser>";
QString xmlOut;

QXmlStreamReader reader(xmlIn);
QXmlStreamWriter writer(&xmlOut);
writer.setAutoFormatting(true);

while (!reader.atEnd()) {
    reader.readNext();
    if (!reader.isWhitespace()) {
        writer.writeCurrentToken(reader);
    }
}

qDebug() << xmlOut;
Dworman answered 19/12, 2012 at 11:21 Comment(4)
Thanks for giving reply . But its breaking during the second iteration .Cort
What do you mean with breaking? Does your program crash? Or do you get unexpected output? This test program should print the output you wanted: gist.github.com/4343585Dworman
ya the program is crashing.Cort
@viku: Could you provide more details about the crash you have (backtrace, error message...)?Dworman
S
3

If you're using Qt, you can read it with QXmlStreamReader and write it with QXmlStreamWriter, or parse it as QDomDocument and convert that back to QString. Both QXmlStreamWriter and QDomDocument support formatting.

Switcheroo answered 19/12, 2012 at 8:4 Comment(0)
S
3

If you want a simple robust solution that does not rely on QT, you can use libxml2. (If you are using QT anyway, just use what Frank Osterfeld said.)

xmlDoc* xdoc = xmlReadFile(BAD_CAST"myfile.xml", NULL, NULL, 0);
xmlSaveFormatFile(BAD_CAST"myfilef.xml", xdoc, 1);
xmlFreeDoc(xdoc);

Can I interest you in my C++ wrapper of libxml2?

Edit: If you happen to have the XML string in memory, you may also use xmlReadDoc... But it doesn't stop there.

Swob answered 19/12, 2012 at 8:58 Comment(0)
C
3
void format(void)
{
    QDomDocument input;

    QFile inFile("D:/input.xml");
    QFile outFile("D:/output.xml");

    inFile.open(inFile.Text | inFile.ReadOnly);
    outFile.open(outFile.Text | outFile.WriteOnly);

    input.setContent(&inFile);

    QDomDocument output(input);
    QTextStream stream(&outFile);
    output.save(stream, 2);
}
Cort answered 21/12, 2012 at 5:47 Comment(0)
W
0

Utilising C++ you can add a single character between each instance of >< for output: by changing >< to >\n< (this adds the non-printing character for a newline) each tag will print onto a new line. There are API ways to do this however as mentioned above, but for a simple way to do what you suggest for console output, or so that the XML flows onto new lines per tag in something like a text editor, the \n should work fine.

If you need a more elegant output, you can code a method yourself using \n (newline) and \t (tab) to lay out your output, or utilise an api if you reeqire a more elaborate representation.

Worn answered 19/12, 2012 at 8:29 Comment(2)
Actually i want to store the above output in to a file . But i think \n will work only for the console . Can you please suggest something for storing it in a file .Cort
How are you streaming to file? For example then the \n will work too if you are saving your xml string as a text file, so you should be fine that way too. You could use an additional API I suppose to prettify your xml output, however, the advantages to writing your own system are that you get to see how everything works; and, you can write as small and efficient a system as you need for your purposes. Its horses for courses really, but if you need a more detailed answer I will do my best, just need some extra info on how you are actually saving the content to file. :)Worn

© 2022 - 2024 — McMap. All rights reserved.