📄 xmlwriter.java
字号:
element = createElement(namespace.alias, namespace.uri, name); } else { element = createElement(null, null, name); } Element parentElement = currentElement(); if (parentElement != null) { element.xmlLang = parentElement.xmlLang; if (parentElement.repeatingCount != Element.NOT_REPEATING) { element.repeatingIndex = parentElement.repeatingCount++; } } elementStack.push(element); if (nextDefaultNamespace != null) { Namespace defaultNs = new Namespace(null, nextDefaultNamespace); element.addNamespace(defaultNs); nextDefaultNamespace = null; } if (namespaceDecls != null) { for (Namespace ns: namespaceDecls) { ensureNamespace(ns); } } if (namespace != null) { element.nsAlias = ensureNamespace(namespace); } writeOpenTagStart(element.nsAlias, name); for (Namespace ns: element.nsDecls) { if (ns.alias != null && ns.alias.length() > 0) { writeAttribute("xmlns", ns.alias, ns.uri); // xmlns:name=uri } else { writeAttribute(null, "xmlns", ns.uri); // xmlns=uri } } if (attrs != null) { for (Attribute attr: attrs) { // Don't write out xml:lang if consistent with the current state. if (attr.name.equals("lang") && "xml".equals(attr.nsAlias)) { if (attr.value.equals(element.xmlLang)) { continue; } else { element.xmlLang = attr.value; } } writeAttribute(attr.nsAlias, attr.name, attr.value); } } writeOpenTagEnd(); } /** * Ends the current element. It is expected to be on top of the stack. * * @param namespace element namespace. * @param name element name. */ public void endElement(Namespace namespace, String name) throws IOException { Element element = currentElement(); assert namespace == null || element.nsUri.equals(namespace.uri); assert element.name.equals(name); endElement(); } /** * Ends the current element. No integrity checking is performed. */ public void endElement() throws IOException { Element element = currentElement(); writeCloseTag(element.nsAlias, element.name); elementStack.pop(); // Write the footer if we're down to just the dummy element. if (elementStack.size() == 1) { writeFooter(); } } /** * Emits a simple element (without child elements). * * @param name element name. * @param value element value. Can be {@code null}. * @throws IOException thrown by the underlying writer. */ public void simpleElement(String name, String value) throws IOException { simpleElement(null, name, null, value); } /** * Indicates that a series of repeating elements are about to * be written. */ public void startRepeatingElement() throws IOException { Element currentElement = currentElement(); if (currentElement.repeatingCount != Element.NOT_REPEATING) { throw new IllegalStateException("Existing repeating element is active"); } currentElement.repeatingCount = 0; } /** * Indicates that the series of repeating elements have been completely * written. */ public void endRepeatingElement() throws IOException { currentElement().repeatingCount = Element.NOT_REPEATING; } /** * Emits a simple element (without child elements). * * @param namespace element namespace. * @param name element name. * @param attrs attributes. Can be {@code null}. * @param value element value. Can be {@code null}. * @throws IOException thrown by the underlying writer. */ public void simpleElement(Namespace namespace, String name, List<Attribute> attrs, String value) throws IOException { startElement(namespace, name, attrs, null); characters(value); endElement(namespace, name); } /** * Determines if the specified namespace is declared at the current scope. * * @return namespace alias if declared. * {@code null} otherwise. */ private String checkNamespace(String namespaceUri) { // Walk the stack from the top to find an element with this ns declaration. for (int i = elementStack.size() - 1; i >= 0; --i) { Element element = elementStack.get(i); for (Namespace ns: element.nsDecls) { if (ns.alias != null && ns.uri.equals(namespaceUri)) { return ns.alias; } } } return null; } /** * Ensures the namespace is in scope and returns its alias. * The top of the stack is assumed to be the current element. * If the namespace is not found, it is appended to the current element. * * @return namespace alias or {@code null} for the default namespace. */ private String ensureNamespace(Namespace namespace) { // Return the default namespace if possible. There is no need to add // here, as it has already been added (with a null alias) by startElement() // if the default namespace is set or changed. if (namespace.uri.equals(defaultNamespace)) { return null; } String alias = checkNamespace(namespace.uri); // If not found, insert this namespace. if (alias == null) { Element current = currentElement(); ensureUniqueNamespaceAlias(current, namespace); current.addNamespace(namespace); alias = namespace.alias; } return alias; } /** * Ensures a unique namespace alias within an element. If the alias has * already been associated with a different URI, then a unique alias prefix * value will be set for the namespace. * * @param element the element to check. * @param namespace the XML namespace to ensure. */ private void ensureUniqueNamespaceAlias(Element element, Namespace namespace) { boolean unique; int serial = 0; do { unique = true; for (Namespace ns: element.nsDecls) { if (namespace.alias.equals(ns.alias)) { unique = false; namespace.alias = "ns" + String.valueOf(++serial); break; } } } while (!unique); } /** * Writes basic XML headers including XML version and encoding. * @param encoding the XML encoding for the output. Can be {@code null}. * @throws IOException thrown by the underlying writer. */ protected void writeHeader(String encoding) throws IOException { writer.write("<?xml"); writeAttribute("version", "1.0"); if (encoding != null) { writeAttribute("encoding", encoding); } writer.write("?>"); } /** * Writes any closing information to the output writer. This is used by * subclasses to write anything they need to close out the object. * {@link #close()} should not be used because it closes the underlying * stream, which we don't always want to do. * * @throws IOException thrown by the underlying writer. */ protected void writeFooter() throws IOException { } /** * Writes a namespace qualified element or attribute name. * * @param nsAlias namespace alias prefix. * @param name namespace-relative local name. * @throws IOException thrown by the underlying writer. */ protected void writeQualifiedName(String nsAlias, String name) throws IOException { if (nsAlias != null && nsAlias.length() > 0) { writer.write(nsAlias); writer.write(':'); } writer.write(name); } /** * Writes the start of the opening tag of an element. * * @param nsAlias namespace alias prefix for the element. * @param name tag name for the element. * @throws IOException thrown by the underlying writer. */ protected void writeOpenTagStart(String nsAlias, String name) throws IOException { writer.write('<'); writeQualifiedName(nsAlias, name); } /** * Writes the end of the opening tag of an element after all attributes * have been written. * * @throws IOException thrown by the underlying writer. */ protected void writeOpenTagEnd() throws IOException { writer.write('>'); } /** * Writes the closing tag of an element, after all nested elements and * value text have been written. * * @param nsAlias namespace alias prefix for the element. * @param name tag name for the element. * @throws IOException thrown by the underlying writer. */ protected void writeCloseTag(String nsAlias, String name) throws IOException { writer.write("</"); writeQualifiedName(nsAlias, name); writer.write(">"); } /** * Writes an unqualfied XML attribute. * * @param name the name of the attribute. * @param value the value of the attribute. * @throws IOException thrown by the underlying writer. */ protected void writeAttribute(String name, String value) throws IOException { writeAttribute(null, name, value); } /** * Writes a namespace-qualified XML attribute. * * @param nsAlias namespace alias prefix for the attribute. * @param name the name of the attribute. * @param value the value of the attribute. * @throws IOException thrown by the underlying writer. */ protected void writeAttribute(String nsAlias, String name, String value) throws IOException { writer.write(" "); writeQualifiedName(nsAlias, name); writer.write('='); writer.write('\''); if (value != null) { writer.write(StringUtil.xmlEscape(value)); } writer.write('\''); } /** * Emits character data subject to XML escaping. * * @param s string to emit. Can be {@code null}. * @throws IOException thrown by the underlying writer. */ public void characters(String s) throws IOException { if (s == null) { return; } writer.write(StringUtil.xmlContentEscape(s)); } /** * Writes inner XML provided as a string. Used to write out XML blobs. * * @param xml XML blob string. * @throws IOException thrown by the underlying writer. */ public void innerXml(String xml) throws IOException { if (xml != null) { writer.write(xml); } } /** * Writes a string without XML entity escaping. Used by * {@link com.google.gdata.util.XmlParser} to generate XML blobs. * * @param s the raw content to write without escaping. * @throws IOException thrown by the underlying writer. */ public void writeUnescaped(String s) throws IOException { writer.write(s); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -