domwalker.java

来自「jsr170接口的java实现。是个apache的开源项目。」· Java 代码 · 共 221 行

JAVA
221
字号
/* * 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.jackrabbit.core.util;import org.w3c.dom.Attr;import org.w3c.dom.CharacterData;import org.w3c.dom.Document;import org.w3c.dom.Element;import org.w3c.dom.NamedNodeMap;import org.w3c.dom.Node;import org.w3c.dom.NodeList;import javax.xml.parsers.DocumentBuilder;import javax.xml.parsers.DocumentBuilderFactory;import java.io.IOException;import java.io.InputStream;import java.util.Properties;/** * Document walker class. This class provides an intuitive * interface for traversing a parsed DOM document. */public final class DOMWalker {    /** Static factory for creating stream to DOM transformers. */    private static final DocumentBuilderFactory factory =        DocumentBuilderFactory.newInstance();    /** The DOM document being traversed by this walker. */    private final Document document;    /** The current element. */    private Element current;    /**     * Creates a walker for traversing a DOM document read from the given     * input stream. The root element of the document is set as the current     * element.     *     * @param xml XML input stream     * @throws IOException if a document cannot be read from the stream     */    public DOMWalker(InputStream xml) throws IOException {        try {            DocumentBuilder builder = factory.newDocumentBuilder();            document = builder.parse(xml);            current = document.getDocumentElement();        } catch (IOException e) {            throw e;        } catch (Exception e) {            throw (IOException) new IOException(e.getMessage()).initCause(e);        }    }    /**     * Returns the namespace mappings defined in the current element.     * The returned property set contains the prefix to namespace     * mappings specified by the <code>xmlns</code> attributes of the     * current element.     *     * @return prefix to namespace mappings of the current element     */    public Properties getNamespaces() {        Properties namespaces = new Properties();        NamedNodeMap attributes = current.getAttributes();        for (int i = 0; i < attributes.getLength(); i++) {            Attr attribute = (Attr) attributes.item(i);            if (attribute.getName().startsWith("xmlns:")) {                namespaces.setProperty(                        attribute.getName().substring(6), attribute.getValue());            }        }        return namespaces;    }    /**     * Returns the name of the current element.     *     * @return element name     */    public String getName() {        return current.getNodeName();    }    /**     * Returns the value of the named attribute of the current element.     *     * @param name attribute name     * @return attribute value, or <code>null</code> if not found     */    public String getAttribute(String name) {        Attr attribute = current.getAttributeNode(name);        if (attribute != null) {            return attribute.getValue();        } else {            return null;        }    }    /**     * Returns the text content of the current element.     *     * @return text content     */    public String getContent() {        StringBuffer content = new StringBuffer();        NodeList nodes = current.getChildNodes();        for (int i = 0; i < nodes.getLength(); i++) {            Node node = nodes.item(i);            if (node.getNodeType() == Node.TEXT_NODE) {                content.append(((CharacterData) node).getData());            }        }        return content.toString();    }    /**     * Enters the named child element. If the named child element is     * found, then it is made the current element and <code>true</code>     * is returned. Otherwise the current element is not changed and     * <code>false</code> is returned.     * <p>     * The standard call sequence for this method is show below.     * <pre>     *     DOMWalker walker = ...;     *     if (walker.enterElement("...")) {     *         ...;     *         walker.leaveElement();     *     }     * </pre>     *     * @param name child element name     * @return <code>true</code> if the element was entered,     *         <code>false</code> otherwise     */    public boolean enterElement(String name) {        NodeList children = current.getChildNodes();        for (int i = 0; i < children.getLength(); i++) {            Node child = children.item(i);            if (child.getNodeType() == Node.ELEMENT_NODE                    && name.equals(child.getNodeName())) {                current = (Element) child;                return true;            }        }        return false;    }    /**     * Leaves the current element. The parent element is set as the new     * current element.     *     * @see #enterElement(String)     */    public void leaveElement() {        current = (Element) current.getParentNode();    }    /**     * Iterates through the named child elements over multiple calls.     * This method makes it possible to use the following code to     * walk through all the child elements with the given name.     * <pre>     *     DOMWalker walker = ...;     *     while (walker.iterateElements("...")) {     *         ...;     *     }     * </pre>     * <p>     * <strong>WARNING:</strong> This method should only be used when     * <code>walker.getName()</code> does not equal <code>name</code> when     * the while loop is started. Otherwise the walker will not be positioned     * at the same node when the while loop ends.     *     * @param name name of the iterated elements     * @return <code>true</code> if another iterated element was entered, or     *         <code>false</code> if no more iterated elements were found     *         and the original element is restored as the current element     */    public boolean iterateElements(String name) {        Node next;        if (name.equals(current.getNodeName())) {            next = current.getNextSibling();        } else {            next = current.getFirstChild();        }        while (next != null) {            if (next.getNodeType() == Node.ELEMENT_NODE                    && name.equals(next.getNodeName())) {                current = (Element) next;                return true;            } else {                next = next.getNextSibling();            }        }        if (name.equals(current.getNodeName())) {            current = (Element) current.getParentNode();        }        return false;    }}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?