00001 //$Header: /home/ben/Mapper/c++/RCS/DOM_output.cpp,v 6.6 2002/07/06 17:41:49 ben Exp $
00002 // Copyright Benedict Adamson 2002.
00003 // This file is part of Mapper.
00004
00005 // Mapper is free software; you can redistribute it and/or modify
00006 // it under the terms of the GNU General Public License as published by
00007 // the Free Software Foundation; either version 2 of the License, or
00008 // (at your option) any later version.
00009
00010 // Mapper is distributed in the hope that it will be useful,
00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00013 // GNU General Public License for more details.
00014
00015 // You should have received a copy of the GNU General Public License
00016 // along with Mapper; if not, write to the Free Software
00017 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
00018
00029 #include <cassert>
00030 #include <cstdio>
00031 #include <iostream>
00032
00033 #include <dom/DOM_Element.hpp>
00034 #include <dom/DOM_CDATASection.hpp>
00035 #include <dom/DOM_Comment.hpp>
00036 #include <dom/DOM_Document.hpp>
00037 #include <dom/DOM_DocumentType.hpp>
00038 #include <dom/DOM_EntityReference.hpp>
00039 #include <dom/DOM_NamedNodeMap.hpp>
00040 #include <dom/DOM_NodeList.hpp>
00041 #include <dom/DOM_ProcessingInstruction.hpp>
00042 #include <dom/DOM_Text.hpp>
00043
00044 #include "DOM_output.h"
00045
00046
00047
00048 void DOM_output::write(
00049 ostream &out,
00050 const DOMString &s
00051 )
00052 {
00053 const char *c = s.transcode();
00054 out << c;
00055 delete c;
00056 }
00057
00058
00059
00060 void DOM_output::write(
00061 ostream &out,
00062 const DOM_Element &elem
00063 )
00064 {
00065 write_tag( out, elem );
00066 write_children( out, elem );
00067 if( elem.hasChildNodes() ){
00068 //output end tag
00069 DOMString tag( elem.getTagName() );
00070 out << "</";
00071 write( out, tag );
00072 out << '>';
00073 };
00074 }
00075
00076
00077
00078 void DOM_output::write(
00079 ostream &out,
00080 const DOM_CDATASection &node
00081 )
00082 {
00083 DOMString text( node.getData() );
00084 out << "<![CDATA[";
00085 write( out, text );
00086 out << "]]>";
00087 }
00088
00089
00090
00091 void DOM_output::write(
00092 ostream &out,
00093 const DOM_EntityReference &node
00094 )
00095 {
00096 DOMString name( node.getNodeName() );
00097 write( out, name );
00098 }
00099
00100
00101
00102 void DOM_output::write(
00103 ostream &out,
00104 const DOM_ProcessingInstruction &node
00105 )
00106 {
00107 out << "<?";
00108 write( out, node.getTarget() );
00109 out << ' ';
00110 write( out, node.getData() );
00111 out << "?>\n";
00112 }
00113
00114
00115
00116 void DOM_output::write(
00117 ostream &out,
00118 const DOM_Comment &node
00119 )
00120 {
00121 out << "<!--";
00122 write( out, node.getData() );
00123 out << "-->";
00124 }
00125
00126
00127
00128 void DOM_output::write(
00129 ostream &out,
00130 const DOM_DocumentType &node
00131 )
00132 {
00133 out << "<!DOCTYPE ";
00134 write( out, node.getName() );
00135 out << " SYSTEM \"";
00136 write( out, node.getSystemId() );
00137 out << "\">\n";
00138 }
00139
00140
00141
00142 void DOM_output::write(
00143 ostream &out,
00144 const DOM_Text &node
00145 )
00146 {
00147 write( out, node.getData() );
00148 }
00149
00150
00151
00152 void DOM_output::write(
00153 ostream &out,
00154 const DOM_Node &node
00155 )
00156 {
00157 switch( node.getNodeType() ){
00158 case DOM_Node::ELEMENT_NODE:
00159 write(
00160 out, static_cast< const DOM_Element & >( node )
00161 );
00162 break;
00163 case DOM_Node::CDATA_SECTION_NODE:
00164 write(
00165 out, static_cast< const DOM_CDATASection & >( node )
00166 );
00167 break;
00168 case DOM_Node::ENTITY_REFERENCE_NODE:
00169 write(
00170 out, static_cast< const DOM_EntityReference & >( node )
00171 );
00172 break;
00173 case DOM_Node::PROCESSING_INSTRUCTION_NODE:
00174 write(
00175 out, static_cast< const DOM_ProcessingInstruction & >( node )
00176 );
00177 break;
00178 case DOM_Node::COMMENT_NODE:
00179 write(
00180 out, static_cast< const DOM_Comment & >( node )
00181 );
00182 break;
00183 case DOM_Node::DOCUMENT_TYPE_NODE:
00184 write(
00185 out, static_cast< const DOM_DocumentType & >( node )
00186 );
00187 break;
00188 case DOM_Node::XML_DECL_NODE:
00189 //Do nothing, already output
00190 break;
00191 case DOM_Node::TEXT_NODE:
00192 write(
00193 out, static_cast< const DOM_Text & >( node )
00194 );
00195 break;
00196 case DOM_Node::DOCUMENT_NODE:
00197 write(
00198 out, static_cast< const DOM_Document & >( node )
00199 );
00200 break;
00201 case DOM_Node::ATTRIBUTE_NODE:
00202 case DOM_Node::ENTITY_NODE:
00203 case DOM_Node::DOCUMENT_FRAGMENT_NODE:
00204 case DOM_Node::NOTATION_NODE:
00205 default:
00206 #ifndef NDEBUG
00207 abort(); //not implemented
00208 #endif
00209 break;
00210 };
00211 }
00212
00213
00214
00215 void DOM_output::write_tag(
00216 ostream &out,
00217 const DOM_Element &elem
00218 )
00219 {
00220 out << '<';
00221 DOMString tag( elem.getTagName() );
00222 write( out, tag );
00223 {//output the attributes
00224 DOM_NamedNodeMap nodes( elem.getAttributes() );
00225 for( unsigned i=0; i < nodes.getLength(); i++ ){
00226 DOM_Node node( nodes.item(i) );
00227 assert( !node.isNull() );
00228 DOM_Attr &attr(
00229 static_cast< DOM_Attr & >( node )
00230 );
00231 out << ' ';
00232 write( out, attr.getName() );
00233 out << "=\"";
00234 write( out, attr.getValue() );
00235 out << '"';
00236 };
00237 };
00238 if( !elem.hasChildNodes() )
00239 out << '/';
00240 ;
00241 out << '>';
00242 }
00243
00244
00245
00246 void DOM_output::write_children(
00247 ostream &out,
00248 const DOM_Node &node
00249 )
00250 {
00251 DOM_Node child( node.getFirstChild() );
00252 while( !child.isNull() ){
00253 write( out, child );
00254 child = child.getNextSibling();
00255 };
00256 }
00257
00258
00259
00260 void DOM_output::write(
00261 ostream &out,
00262 const DOM_Document &doc
00263 )
00264 {
00265 out << "<?xml version=\"1.0\" standalone=\"no\"?>\n";
00266 write_children( out, doc );
00267 }
00268
00269
00270
00271 void DOM_output::traceback(
00272 ostream &out,
00273 const DOM_Element &elem
00274 )
00275 {
00276 out << "in ";
00277 write_tag( out, elem );
00278 out << '\n';
00279 DOM_Node parent( elem.getParentNode() );
00280 if( parent.getNodeType() == DOM_Node::ELEMENT_NODE )
00281 traceback( out, static_cast< const DOM_Element & >( parent ) );
00282 ;
00283 }