1/* 2 Copyright (C) 2000-2009 SKYRIX Software AG 3 4 This file is part of SOPE. 5 6 SOPE is free software; you can redistribute it and/or modify it under 7 the terms of the GNU Lesser General Public License as published by the 8 Free Software Foundation; either version 2, or (at your option) any 9 later version. 10 11 SOPE is distributed in the hope that it will be useful, but WITHOUT ANY 12 WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 14 License for more details. 15 16 You should have received a copy of the GNU Lesser General Public 17 License along with SOPE; see the file COPYING. If not, write to the 18 Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 19 02111-1307, USA. 20*/ 21 22#include "DOMPYXOutputter.h" 23#include "DOMDocument.h" 24#include "DOMElement.h" 25#include "common.h" 26 27@interface NGDOMPYXOutputter(Privates) 28- (void)outputNode:(id)_node to:(id)_target; 29- (void)outputNodeList:(id)_nodeList to:(id)_target; 30@end 31 32@implementation NGDOMPYXOutputter 33 34- (void)write:(NSString *)s to:(id)_target { 35#ifndef __APPLE__ 36 printf("%s", [s cString]); 37#else 38 printf("%s", [s UTF8String]); 39#endif 40} 41- (BOOL)currentElementPreservesWhitespace { 42 return NO; 43} 44 45- (void)outputAttributeNode:(id<DOMAttr>)_attrNode 46 ofNode:(id<DOMNode>)_node 47 to:(id)_target 48{ 49 [self write:@"A" to:_target]; 50 [self write:[_attrNode name] to:_target]; 51 [self write:@" " to:_target]; 52 [self write:[_attrNode nodeValue] to:_target]; 53 [self write:@"\n" to:_target]; 54} 55 56- (void)outputAttributeNodes:(id<DOMNamedNodeMap>)_nodes 57 ofNode:(id<DOMNode>)_node 58 to:(id)_target 59{ 60 unsigned i, count; 61 62 if ((count = [_nodes length]) == 0) 63 return; 64 65 for (i = 0; i < count; i++) { 66 [self outputAttributeNode:[_nodes objectAtIndex:i] 67 ofNode:_node 68 to:_target]; 69 } 70} 71 72- (void)outputTextNode:(id<DOMText>)_node to:(id)_target { 73 NSString *s; 74 unsigned len; 75 76 s = [_node data]; 77 if ((len = [s length]) == 0) 78 return; 79 80 if ([s rangeOfString:@"\n"].length != 0) { 81 s = [[s componentsSeparatedByString:@"\n"] 82 componentsJoinedByString:@"\\n"]; 83 } 84 85 [self write:@"-" to:_target]; 86 [self write:s to:_target]; 87 [self write:@"\n" to:_target]; 88} 89- (void)outputCommentNode:(id<DOMComment>)_node to:(id)_target { 90 [self write:@"<!-- " to:_target]; 91 [self write:[_node data] to:_target]; 92 [self write:@" -->" to:_target]; 93 94 if (![self currentElementPreservesWhitespace]) 95 [self write:@"\n" to:_target]; 96} 97 98- (void)outputElementNode:(id<DOMElement>)_node to:(id)_target { 99 NSString *tagName; 100 // NSString *ns; 101 102 /* needs to declare namespaces !!! */ 103 tagName = [_node tagName]; 104 if ([[_node prefix] length] > 0) { 105 NSString *p = [_node prefix]; 106 107 p = [p stringByAppendingString:@":"]; 108 tagName = [p stringByAppendingString:tagName]; 109 110 // ns = [NSString stringWithFormat:@" xmlns:%@=\"%@\"", 111 // [_node prefix], 112 // [_node namespaceURI]]; 113 } 114 // else if ([[_node namespaceURI] length] > 0) { 115 // ns = [NSString stringWithFormat:@" xmlns=\"%@\"", [_node namespaceURI]]; 116 // } 117 // else 118 // ns = nil; 119 120 [self write:@"(" to:_target]; 121 [self write:tagName to:_target]; 122 [self write:@"\n" to:_target]; 123 124 [self outputAttributeNodes:[_node attributes] ofNode:_node to:_target]; 125 126 if ([_node hasChildNodes]) 127 [self outputNodeList:[_node childNodes] to:_target]; 128 129 [self write:@")" to:_target]; 130 [self write:tagName to:_target]; 131 [self write:@"\n" to:_target]; 132} 133 134- (void)outputCDATA:(id<DOMCharacterData>)_node to:(id)_target { 135 NSString *s; 136 137 s = [_node data]; 138 139 if ([s rangeOfString:@"\n"].length != 0) { 140 /* escape newlines */ 141 s = [[s componentsSeparatedByString:@"\n"] 142 componentsJoinedByString:@"\\n"]; 143 } 144 145 [self write:@"-" to:_target]; 146 [self write:s to:_target]; 147 [self write:@"\n" to:_target]; 148} 149 150- (void)outputPI:(id<DOMProcessingInstruction>)_node to:(id)_target { 151 [self write:@"?" to:_target]; 152 [self write:[_node target] to:_target]; 153 [self write:@" " to:_target]; 154 [self write:[_node data] to:_target]; 155 [self write:@"\n" to:_target]; 156} 157 158- (void)outputNode:(id)_node to:(id)_target { 159 switch ([_node nodeType]) { 160 case DOM_ELEMENT_NODE: 161 [self outputElementNode:_node to:_target]; 162 break; 163 case DOM_CDATA_SECTION_NODE: 164 [self outputCDATA:_node to:_target]; 165 break; 166 case DOM_PROCESSING_INSTRUCTION_NODE: 167 [self outputPI:_node to:_target]; 168 break; 169 case DOM_TEXT_NODE: 170 [self outputTextNode:_node to:_target]; 171 break; 172 case DOM_COMMENT_NODE: 173 [self outputCommentNode:_node to:_target]; 174 break; 175 176 default: 177 NSLog(@"cannot output node %@", _node); 178 break; 179 } 180} 181- (void)outputNodeList:(id)_nodeList to:(id)_target { 182 id children; 183 unsigned i, count; 184 185 children = _nodeList; 186 187 for (i = 0, count = [children count]; i < count; i++) 188 [self outputNode:[children objectAtIndex:i] to:_target]; 189} 190 191- (void)outputDocument:(id)_document to:(id)_target { 192 if (![_document hasChildNodes]) 193 return; 194 195 NS_DURING 196 [self outputNodeList:[_document childNodes] to:_target]; 197 NS_HANDLER 198#ifndef __APPLE__ 199 fprintf(stderr, "%s\n", [[localException description] cString]); 200#else 201 fprintf(stderr, "%s\n", [[localException description] UTF8String]); 202#endif 203#if DEBUG 204 abort(); 205#endif 206 NS_ENDHANDLER; 207} 208 209@end /* DOMPYXOutputter */ 210