📄 domelementwriter.java
字号:
/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You 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 org.apache.tools.ant.util;import java.io.IOException;import java.io.OutputStream;import java.io.OutputStreamWriter;import java.io.Writer;import java.util.ArrayList;import java.util.HashMap;import java.util.Iterator;import org.w3c.dom.Attr;import org.w3c.dom.Element;import org.w3c.dom.NamedNodeMap;import org.w3c.dom.Node;import org.w3c.dom.NodeList;import org.w3c.dom.Text;/** * Writes a DOM tree to a given Writer. * warning: this utility currently does not declare XML Namespaces. * <p>Utility class used by {@link org.apache.tools.ant.XmlLogger * XmlLogger} and * org.apache.tools.ant.taskdefs.optional.junit.XMLJUnitResultFormatter * XMLJUnitResultFormatter}.</p> * */public class DOMElementWriter { private static final int HEX = 16; /** prefix for generated prefixes */ private static final String NS = "ns"; /** xml declaration is on by default */ private boolean xmlDeclaration = true; /** * XML Namespaces are ignored by default. */ private XmlNamespacePolicy namespacePolicy = XmlNamespacePolicy.IGNORE; /** * Map (URI to prefix) of known namespaces. */ private HashMap nsPrefixMap = new HashMap(); /** * Number of generated prefix to use next. */ private int nextPrefix = 0; /** * Map (Element to URI) of namespaces defined on a given element. */ private HashMap nsURIByElement = new HashMap(); /** * Whether namespaces should be ignored for elements and attributes. * * @since Ant 1.7 */ public static class XmlNamespacePolicy { private boolean qualifyElements; private boolean qualifyAttributes; /** * Ignores namespaces for elements and attributes, the default. */ public static final XmlNamespacePolicy IGNORE = new XmlNamespacePolicy(false, false); /** * Ignores namespaces for attributes. */ public static final XmlNamespacePolicy ONLY_QUALIFY_ELEMENTS = new XmlNamespacePolicy(true, false); /** * Qualifies namespaces for elements and attributes. */ public static final XmlNamespacePolicy QUALIFY_ALL = new XmlNamespacePolicy(true, true); /** * @param qualifyElements whether to qualify elements * @param qualifyAttributes whether to qualify elements */ public XmlNamespacePolicy(boolean qualifyElements, boolean qualifyAttributes) { this.qualifyElements = qualifyElements; this.qualifyAttributes = qualifyAttributes; } } /** * Create an element writer. * The ?xml? declaration will be included, namespaces ignored. */ public DOMElementWriter() { } /** * Create an element writer * XML namespaces will be ignored. * @param xmlDeclaration flag to indicate whether the ?xml? declaration * should be included. * @since Ant1.7 */ public DOMElementWriter(boolean xmlDeclaration) { this(xmlDeclaration, XmlNamespacePolicy.IGNORE); } /** * Create an element writer * XML namespaces will be ignored. * @param xmlDeclaration flag to indicate whether the ?xml? declaration * should be included. * @param namespacePolicy the policy to use. * @since Ant1.7 */ public DOMElementWriter(boolean xmlDeclaration, XmlNamespacePolicy namespacePolicy) { this.xmlDeclaration = xmlDeclaration; this.namespacePolicy = namespacePolicy; } private static String lSep = System.getProperty("line.separator"); // CheckStyle:VisibilityModifier OFF - bc /** * Don't try to be too smart but at least recognize the predefined * entities. */ protected String[] knownEntities = {"gt", "amp", "lt", "apos", "quot"}; // CheckStyle:VisibilityModifier ON /** * Writes a DOM tree to a stream in UTF8 encoding. Note that * it prepends the <?xml version='1.0' encoding='UTF-8'?> if * the xmlDeclaration field is true. * The indent number is set to 0 and a 2-space indent. * @param root the root element of the DOM tree. * @param out the outputstream to write to. * @throws IOException if an error happens while writing to the stream. */ public void write(Element root, OutputStream out) throws IOException { Writer wri = new OutputStreamWriter(out, "UTF8"); writeXMLDeclaration(wri); write(root, wri, 0, " "); wri.flush(); } /** * Writes the XML declaration if xmlDeclaration is true. * @param wri the writer to write to. * @throws IOException if there is an error. * @since Ant 1.7.0 */ public void writeXMLDeclaration(Writer wri) throws IOException { if (xmlDeclaration) { wri.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"); } } /** * Writes a DOM tree to a stream. * * @param element the Root DOM element of the tree * @param out where to send the output * @param indent number of * @param indentWith string that should be used to indent the * corresponding tag. * @throws IOException if an error happens while writing to the stream. */ public void write(Element element, Writer out, int indent, String indentWith) throws IOException { // Write child elements and text NodeList children = element.getChildNodes(); boolean hasChildren = (children.getLength() > 0); boolean hasChildElements = false; openElement(element, out, indent, indentWith, hasChildren); if (hasChildren) { for (int i = 0; i < children.getLength(); i++) { Node child = children.item(i); switch (child.getNodeType()) { case Node.ELEMENT_NODE: hasChildElements = true; if (i == 0) { out.write(lSep); } write((Element) child, out, indent + 1, indentWith); break; case Node.TEXT_NODE: out.write(encode(child.getNodeValue())); break; case Node.COMMENT_NODE: out.write("<!--"); out.write(encode(child.getNodeValue())); out.write("-->"); break; case Node.CDATA_SECTION_NODE: out.write("<![CDATA["); out.write(encodedata(((Text) child).getData())); out.write("]]>"); break; case Node.ENTITY_REFERENCE_NODE: out.write('&'); out.write(child.getNodeName()); out.write(';'); break; case Node.PROCESSING_INSTRUCTION_NODE: out.write("<?"); out.write(child.getNodeName()); String data = child.getNodeValue(); if (data != null && data.length() > 0) { out.write(' '); out.write(data); } out.write("?>"); break; default: // Do nothing } } closeElement(element, out, indent, indentWith, hasChildElements); } } /** * Writes the opening tag - including all attributes - * corresponding to a DOM element. * * @param element the DOM element to write * @param out where to send the output * @param indent number of * @param indentWith string that should be used to indent the * corresponding tag. * @throws IOException if an error happens while writing to the stream. */ public void openElement(Element element, Writer out, int indent, String indentWith) throws IOException { openElement(element, out, indent, indentWith, true); } /** * Writes the opening tag - including all attributes - * corresponding to a DOM element. * * @param element the DOM element to write * @param out where to send the output * @param indent number of * @param indentWith string that should be used to indent the * corresponding tag. * @param hasChildren whether this element has children. * @throws IOException if an error happens while writing to the stream. * @since Ant 1.7 */ public void openElement(Element element, Writer out, int indent, String indentWith, boolean hasChildren) throws IOException { // Write indent characters for (int i = 0; i < indent; i++) { out.write(indentWith); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -