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.

Vertexwahn
  • 7,709
  • 6
  • 64
  • 90
Viku
  • 2,845
  • 4
  • 35
  • 63
  • 1
    Read the XML with [TinyXML](http://www.grinninglizard.com/tinyxml/), print it out with TiXMLPrinter, which defaults to pretty printing. – Jerry Coffin Dec 19 '12 at 06:37

5 Answers5

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;
stijnvn
  • 356
  • 2
  • 12
  • Thanks for giving reply . But its breaking during the second iteration . – Viku Dec 20 '12 at 06:10
  • 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: https://gist.github.com/4343585 – stijnvn Dec 20 '12 at 07:42
  • ya the program is crashing. – Viku Dec 21 '12 at 05:36
  • @viku: Could you provide more details about the crash you have (backtrace, error message...)? – stijnvn Dec 21 '12 at 09:29
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.

Frank Osterfeld
  • 24,815
  • 5
  • 58
  • 70
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.

rioki
  • 5,988
  • 5
  • 32
  • 55
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);
}
Viku
  • 2,845
  • 4
  • 35
  • 63
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.

GMasucci
  • 2,834
  • 22
  • 42
  • 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 . – Viku Dec 19 '12 at 08:38
  • 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. :) – GMasucci Dec 19 '12 at 11:13