tags:

views:

67

answers:

2

Hi.

I am looking for C++ code to indent an xml line. I don't want to link with a library.

I have my stream in one line like this

<root><a>value_a</a><b>value_b</b></root>

and I want to print it in a multi-line way (with tabs).

<root>
   <a>value_a</a>
   <b>value_b</b>
</root>

does it ring a bell to anybody?

+2  A: 

Use TinyXML


There's a class TiXmlPrinter there, that will do this job for you. Also, working with TiXmlDocument is pretty easy, fast and clear.

Parsing whole XML document is very easy, too. With TinyXML you could manipulate the XML structure like a real tree. There's a really good JavaDoc in the headers of the library.

Kiril Kirov
I cannot add this library in my system. Is there pure C++ code?
cateof
It is pure C++ code, with headers and cpp files. Otherwise, I don't know any other way, probably you will need to write your own parser or printer for XML.
Kiril Kirov
@cateof: You should add this kind if information to you question.
Space_C0wb0y
+2  A: 

If you do not want to use a library, you will have to write it yourself. That should not be too hard. You will first have to tokenize the stream into tags and values. This is the hardest part I guess. Then you have to write the tokens to a stream. For every opening tag that follows an opening tag, you increase the indent, and for every closing tag that follows a closing tag you decrease the indent.

Some hints for the tokenizing. I think what I would try is to write a simple XMLToken class like this:

class XMLToken {
public:
    enum ElementType { OpenTag, CloseTag, Value };
    std::string content;
    ElementType elementType;
};

These members should be encapsulated with appropriate getters and setters, this is just for illustration. Then I would overload the stream extraction operator for this type:

std::istream & operator >>(st::istream & stream, XMLToken & token) {
    // if first char is '<', then token is a tag, otherwise a value
    // read until '>' is found for a tag and until '<' is found for a value
    return stream;
}

Then you can use an istream_iterator for tokenizing the stream:

typedef std::istream_iterator< XMLToken > XMLTokenizer;
for ( XMLTokenizer it = XMLTokenizer(some_istream); it != XMLTokenizer; it++ ) {
    // process token
}

Hope this helps you a bit.

Space_C0wb0y