📄 xmlwriter.java
字号:
/* Copyright (c) 2006 Google Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package com.google.gdata.util.common.xml;import com.google.gdata.util.common.base.StringUtil;import java.io.IOException;import java.io.Writer;import java.util.ArrayList;import java.util.Collection;import java.util.EmptyStackException;import java.util.List;import java.util.Stack;/** * Implements a simple XML writer on top of java.io.PrintWriter. * This implementation can be conveniently used to generate XML responses in * servlets. * * The XmlWriter class exposes a number of protected methods that enable it * to be subclassed for the purposes of customizing its output. See * {@link com.google.javascript.util.JsonWriter} for an example. * * * */public class XmlWriter { /** * The Namespace class represents an XML Namespace that can be associated * with elements or attributes. */ public final static class Namespace { String alias; final String uri; /** Initializes a namespace. */ public Namespace(String alias, String uri) { this.alias = alias; this.uri = uri; } /** * Returns the prefix alias for the namespace. * @returns namespace alias. */ final public String getAlias() { return alias; } /** * Returns the fully qualified URI for the namespace. * @returns namespace URI. */ final public String getUri() { return uri; } @Override public boolean equals(Object obj) { if (! (obj instanceof Namespace)) return false; Namespace other = (Namespace) obj; if (alias == null) { return (other.alias == null) && uri.equals(other.uri); } else { return alias.equals(other.alias) && uri.equals(other.uri); } } @Override public int hashCode() { if (alias == null) { return uri.hashCode(); } else { return alias.hashCode() & uri.hashCode(); } } } /** * The Attribute class represents an XML attribute. */ public final static class Attribute { final String nsAlias; final String name; final String value; /** * Constructs an unqualified XML attribute. * * @param the attribute name. * @param the attribute value. */ public Attribute(String name, String value) { this(null, name, value); } /** * Constructs an namespace-qualified XML attribute. * * @param the attribute namespace prefix alias. * @param the attribute name. * @param the attribute value. */ public Attribute(String nsAlias, String name, String value) { /** * Back compat for clients that use the two-arg constructor to * write namespace qualified attributes of the form "alias:name". */ if (nsAlias == null) { int separator = name.indexOf(':'); if (separator > 0) { nsAlias = name.substring(0, separator); name = name.substring(separator+1); } } this.nsAlias = nsAlias; this.name = name; this.value = value; } /* * Constructs an xsd:boolean-valued XML attribute. * * @param the attribute name. * @param the attribute value. */ public Attribute(String name, boolean value) { this(null, name, value ? "true" : "false"); } } /** * The Element class contains information about an XML element. Used to keep * track of namespace alias/URI mappings. This class may be subclassed * by XmlWriter subclasses that want to track additional information about * output elements. The {@link #createElement} method can be overriden * to instantiate a specialized Element subclass. */ protected static class Element { /** * Sentinel value used for repeating elements. * @see #repeatingCount * @see #repeatingIndex */ public static final int NOT_REPEATING = -1; /** * Namespace declarations associated with this element. */ public List<Namespace> nsDecls; /** * Namespace prefix for the element. */ public String nsAlias; /** * Full namespace uri for the element. */ public final String nsUri; /** * Local name of the element. */ public final String name; /** * xml:lang attribute of the element. */ public String xmlLang; /** * True if the element has attributes. */ public boolean hasAttributes; /** * Indicates the number of repeating child elements written within * the scope of the current {@link #startRepeatingElement} / * {@link endRepeatingElement} pair for this element. The value will be * {@link #NOT_REPEATING} if not currently writing repeating elements. */ public int repeatingCount = NOT_REPEATING; /** * If an element is a part of a series of repeating element within its * parent, this will contain the zero-based index of the child, else * the value will be {@link #NOT_REPEATING}. */ public int repeatingIndex = NOT_REPEATING; /** * Constructs an element. This constructor should never be directly * called, always use the {@link #createElement} method to create new * elements. * * @see #createElement */ protected Element(String nsAlias, String nsUri, String name) { nsDecls = new ArrayList<Namespace>(); this.nsAlias = nsAlias; this.nsUri = nsUri; this.name = name; } /** * Adds a namespace declaration to the element, avoiding duplicates. */ void addNamespace(Namespace ns) { if(!nsDecls.contains(ns)) { nsDecls.add(ns); } } } /** * The underlying output Writer associated with this XmlWriter. */ protected final Writer writer; /** * Stack of currently opened elements. */ private final Stack<Element> elementStack; /** * Current default namespace. */ private String defaultNamespace; /** * The default namespace that will take effect on the next * element transition. */ private String nextDefaultNamespace = null; /** * Constructs an XmlWriter instance associated that will generate * XML content to an underlying {@link Writer}. * * @param w output writer object. * @throws IOException thrown by the underlying writer. */ public XmlWriter(Writer w) throws IOException { writer = w; /* * Create the element stack and push an initial dummy element on it. * This enables parent checking and other basic functionality for * the root element without requiring special case handling of an * empty element stack. */ elementStack = new Stack<Element>(); elementStack.push(createElement(null, null, null)); } /** * Constructor that writers header including encoding information. * * @param w Output writer object. * @param encoding output encoding to use in declaration. * * @throws IOException thrown by the underlying writer. */ public XmlWriter(Writer w, String encoding) throws IOException { this(w); writeHeader(encoding); } // Included for back compat only, deprecated. public XmlWriter(Writer w, boolean includeHeader) throws IOException { this(w); if (includeHeader) { writeHeader(null); } } /** * Closes the XmlWriter and the underlying output writer. * * @throws IOException thrown by the underlying writer. */ public void close() throws IOException { writer.close(); } /** * Sets the default namespace. It takes effect on the next element. * * @param namespace the new namespace to set as the default at the start * of the next element. */ public void setDefaultNamespace(Namespace namespace) { if (!namespace.uri.equals(defaultNamespace)) { nextDefaultNamespace = namespace.uri; defaultNamespace = namespace.uri; } } /** * Constructs an Element instance that describes an XML element that * is about to be written. */ protected Element createElement(String nsAlias, String nsUri, String name) { return new Element(nsAlias, nsUri, name); } /** * Returns the current element, or {@code null} if no element is being * written. */ protected Element currentElement() { try { return elementStack.peek(); } catch (EmptyStackException e) { return null; } } /** * Starts an element. This element can be a parent to other elements. * * @param name element name. */ public void startElement(String name) throws IOException { startElement(null, name, null, null); } /** * Starts an element. This element can be a parent to other elements. * * @param namespace element namespace. * @param name element name. * @param attrs attributes. Can be {@code null}. * @param namespaceDecls extra namespace declarations. Can be {@code null}. * @throws IOException thrown by the underlying writer. */ public void startElement(Namespace namespace, String name, Collection<Attribute> attrs, Collection<Namespace> namespaceDecls) throws IOException { Element element; if (namespace != null) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -