001package org.jsoup.nodes; 002 003import org.jsoup.SerializationException; 004import org.jsoup.helper.Validate; 005 006import java.io.IOException; 007 008/** 009 * An XML Declaration. 010 */ 011public class XmlDeclaration extends LeafNode { 012 // todo this impl isn't really right, the data shouldn't be attributes, just a run of text after the name 013 private final boolean isProcessingInstruction; // <! if true, <? if false, declaration (and last data char should be ?) 014 015 /** 016 * Create a new XML declaration 017 * @param name of declaration 018 * @param isProcessingInstruction is processing instruction 019 */ 020 public XmlDeclaration(String name, boolean isProcessingInstruction) { 021 Validate.notNull(name); 022 value = name; 023 this.isProcessingInstruction = isProcessingInstruction; 024 } 025 026 /** 027 * Create a new XML declaration 028 * @param name of declaration 029 * @param baseUri Leaf Nodes don't have base URIs; they inherit from their Element 030 * @param isProcessingInstruction is processing instruction 031 * @see XmlDeclaration#XmlDeclaration(String, boolean) 032 * @deprecated 033 */ 034 public XmlDeclaration(String name, String baseUri, boolean isProcessingInstruction) { 035 this(name, isProcessingInstruction); 036 } 037 038 public String nodeName() { 039 return "#declaration"; 040 } 041 042 /** 043 * Get the name of this declaration. 044 * @return name of this declaration. 045 */ 046 public String name() { 047 return coreValue(); 048 } 049 050 /** 051 * Get the unencoded XML declaration. 052 * @return XML declaration 053 */ 054 public String getWholeDeclaration() { 055 StringBuilder sb = new StringBuilder(); 056 try { 057 getWholeDeclaration(sb, new Document.OutputSettings()); 058 } catch (IOException e) { 059 throw new SerializationException(e); 060 } 061 return sb.toString().trim(); 062 } 063 064 private void getWholeDeclaration(Appendable accum, Document.OutputSettings out) throws IOException { 065 for (Attribute attribute : attributes()) { 066 if (!attribute.getKey().equals(nodeName())) { // skips coreValue (name) 067 accum.append(' '); 068 attribute.html(accum, out); 069 } 070 } 071 } 072 073 void outerHtmlHead(Appendable accum, int depth, Document.OutputSettings out) throws IOException { 074 accum 075 .append("<") 076 .append(isProcessingInstruction ? "!" : "?") 077 .append(coreValue()); 078 getWholeDeclaration(accum, out); 079 accum 080 .append(isProcessingInstruction ? "!" : "?") 081 .append(">"); 082 } 083 084 void outerHtmlTail(Appendable accum, int depth, Document.OutputSettings out) { 085 } 086 087 @Override 088 public String toString() { 089 return outerHtml(); 090 } 091}