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