129 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			Haxe
		
	
	
	
	
	
			
		
		
	
	
			129 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			Haxe
		
	
	
	
	
	
| /*
 | |
|  * Copyright (C)2005-2019 Haxe Foundation
 | |
|  *
 | |
|  * Permission is hereby granted, free of charge, to any person obtaining a
 | |
|  * copy of this software and associated documentation files (the "Software"),
 | |
|  * to deal in the Software without restriction, including without limitation
 | |
|  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 | |
|  * and/or sell copies of the Software, and to permit persons to whom the
 | |
|  * Software is furnished to do so, subject to the following conditions:
 | |
|  *
 | |
|  * The above copyright notice and this permission notice shall be included in
 | |
|  * all copies or substantial portions of the Software.
 | |
|  *
 | |
|  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | |
|  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | |
|  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | |
|  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | |
|  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 | |
|  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 | |
|  * DEALINGS IN THE SOFTWARE.
 | |
|  */
 | |
| 
 | |
| package haxe.xml;
 | |
| 
 | |
| /**
 | |
| 	This class provides utility methods to convert Xml instances to
 | |
| 	String representation.
 | |
| **/
 | |
| class Printer {
 | |
| 	/**
 | |
| 		Convert `Xml` to string representation.
 | |
| 
 | |
| 		Set `pretty` to `true` to prettify the result.
 | |
| 	**/
 | |
| 	static public function print(xml:Xml, ?pretty = false) {
 | |
| 		var printer = new Printer(pretty);
 | |
| 		printer.writeNode(xml, "");
 | |
| 		return printer.output.toString();
 | |
| 	}
 | |
| 
 | |
| 	var output:StringBuf;
 | |
| 	var pretty:Bool;
 | |
| 
 | |
| 	function new(pretty) {
 | |
| 		output = new StringBuf();
 | |
| 		this.pretty = pretty;
 | |
| 	}
 | |
| 
 | |
| 	function writeNode(value:Xml, tabs:String) {
 | |
| 		switch (value.nodeType) {
 | |
| 			case CData:
 | |
| 				write(tabs + "<![CDATA[");
 | |
| 				write(value.nodeValue);
 | |
| 				write("]]>");
 | |
| 				newline();
 | |
| 			case Comment:
 | |
| 				var commentContent:String = value.nodeValue;
 | |
| 				commentContent = ~/[\n\r\t]+/g.replace(commentContent, "");
 | |
| 				commentContent = "<!--" + commentContent + "-->";
 | |
| 				write(tabs);
 | |
| 				write(StringTools.trim(commentContent));
 | |
| 				newline();
 | |
| 			case Document:
 | |
| 				for (child in value) {
 | |
| 					writeNode(child, tabs);
 | |
| 				}
 | |
| 			case Element:
 | |
| 				write(tabs + "<");
 | |
| 				write(value.nodeName);
 | |
| 				for (attribute in value.attributes()) {
 | |
| 					write(" " + attribute + "=\"");
 | |
| 					write(StringTools.htmlEscape(value.get(attribute), true));
 | |
| 					write("\"");
 | |
| 				}
 | |
| 				if (hasChildren(value)) {
 | |
| 					write(">");
 | |
| 					newline();
 | |
| 					for (child in value) {
 | |
| 						writeNode(child, pretty ? tabs + "\t" : tabs);
 | |
| 					}
 | |
| 					write(tabs + "</");
 | |
| 					write(value.nodeName);
 | |
| 					write(">");
 | |
| 					newline();
 | |
| 				} else {
 | |
| 					write("/>");
 | |
| 					newline();
 | |
| 				}
 | |
| 			case PCData:
 | |
| 				var nodeValue:String = value.nodeValue;
 | |
| 				if (nodeValue.length != 0) {
 | |
| 					write(tabs + StringTools.htmlEscape(nodeValue));
 | |
| 					newline();
 | |
| 				}
 | |
| 			case ProcessingInstruction:
 | |
| 				write("<?" + value.nodeValue + "?>");
 | |
| 				newline();
 | |
| 			case DocType:
 | |
| 				write("<!DOCTYPE " + value.nodeValue + ">");
 | |
| 				newline();
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	inline function write(input:String) {
 | |
| 		output.add(input);
 | |
| 	}
 | |
| 
 | |
| 	inline function newline() {
 | |
| 		if (pretty) {
 | |
| 			output.add("\n");
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	function hasChildren(value:Xml):Bool {
 | |
| 		for (child in value) {
 | |
| 			switch (child.nodeType) {
 | |
| 				case Element, PCData:
 | |
| 					return true;
 | |
| 				case CData, Comment:
 | |
| 					if (StringTools.ltrim(child.nodeValue).length != 0) {
 | |
| 						return true;
 | |
| 					}
 | |
| 				case _:
 | |
| 			}
 | |
| 		}
 | |
| 		return false;
 | |
| 	}
 | |
| }
 |