00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00035 #include "OW_config.h"
00036 #include "OW_XMLPrettyPrint.hpp"
00037 #include "OW_XMLParserCore.hpp"
00038 #include "OW_TempFileStream.hpp"
00039 #include "OW_StringBuffer.hpp"
00040 #include "OW_Assertion.hpp"
00041
00042 namespace OW_NAMESPACE
00043 {
00044
00045 static void addIndent(StringBuffer& sb, int indent)
00046 {
00047 while (indent--)
00048 {
00049 sb += " ";
00050 }
00051 }
00052 static void outputAttrs(StringBuffer& sb, const XMLToken& tok)
00053 {
00054 for (size_t i = 0; i < tok.attributeCount; ++i)
00055 {
00056 sb += ' ';
00057 sb += tok.attributes[i].name;
00058 sb += "=\"";
00059 sb += tok.attributes[i].value;
00060 sb += "\"";
00061 }
00062 }
00063 String XMLPrettyPrint(std::istream& istr)
00064 {
00065 XMLParserCore p(istr);
00066 StringBuffer rval;
00067 int indent = 0;
00068 XMLToken tok;
00069 bool good = p.next(tok);
00070 while (good)
00071 {
00072 switch (tok.type)
00073 {
00074 case XMLToken::XML_DECLARATION:
00075 addIndent(rval, indent);
00076 rval += "<?xml";
00077 outputAttrs(rval, tok);
00078 rval += " ?>\n";
00079 break;
00080 case XMLToken::START_TAG:
00081 addIndent(rval, indent);
00082 rval += "<";
00083 rval += tok.text;
00084 outputAttrs(rval, tok);
00085 rval += ">\n";
00086 ++indent;
00087 break;
00088 case XMLToken::END_TAG:
00089 --indent;
00090 OW_ASSERT(indent >= 0);
00091 addIndent(rval, indent);
00092 rval += "</";
00093 rval += tok.text;
00094 rval += ">\n";
00095 break;
00096 case XMLToken::COMMENT:
00097 addIndent(rval, indent);
00098 rval += "<!--";
00099 rval += tok.text;
00100 rval += "-->\n";
00101 break;
00102 case XMLToken::CDATA:
00103 addIndent(rval, indent);
00104 rval += "<![CDATA[";
00105 rval += tok.text;
00106 rval += "]]>\n";
00107 break;
00108 case XMLToken::DOCTYPE:
00109 addIndent(rval, indent);
00110 rval += "<!DOCTYPE";
00111 rval += tok.text;
00112 rval += ">\n";
00113 break;
00114 case XMLToken::CONTENT:
00115 addIndent(rval, indent);
00116 rval += tok.text;
00117 rval += "\n";
00118 break;
00119 default:
00120 OW_ASSERT(0);
00121 }
00122
00123 good = p.next(tok);
00124 }
00125 return rval.releaseString();
00126 }
00127 String XMLPrettyPrint(const String& s)
00128 {
00129 TempFileStream tfs;
00130 tfs << s;
00131 tfs.rewind();
00132 return XMLPrettyPrint(tfs);
00133 }
00134
00135 }
00136