All Downloads are FREE. Search and download functionalities are using the official Maven repository.

javaxt.xml.DOM Maven / Gradle / Ivy

package javaxt.xml;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
//imports used to transform xml
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

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;

//******************************************************************************
//**  DOM Utilities - By Peter Borissow
//******************************************************************************
/**
 * Provides basic utilities to simplify loading and parsing xml
 *
 ******************************************************************************/

public class DOM {

	// **************************************************************************
	// ** Private Constructor
	// **************************************************************************
	/** Defeats Instantiation */

	private DOM() {
	}

	// **************************************************************************
	// ** createDocument
	// **************************************************************************
	/** Used to create a DOM document from a URL. */

	public static Document createDocument(java.net.URL url) {
		return new javaxt.http.Request(url).getResponse().getXML();
	}

	// **************************************************************************
	// ** createDocument
	// **************************************************************************
	/**
	 * Used to create a DOM document from a java.io.File. Returns null if the
	 * file cannot be serialized to XML.
	 */
	public static Document createDocument(java.io.File file) {
		if (file.exists() == false)
			return null;
		try {
			return createDocument(new java.io.FileInputStream(file));
		} catch (Exception e) {
			// e.printStackTrace();
			return null;
		}
	}

	// **************************************************************************
	// ** createDocument
	// **************************************************************************
	/**
	 * Used to create a DOM document from a String. Returns null if the string
	 * is invalid.
	 */
	public static Document createDocument(String xml) {
		if (xml == null)
			return null;

		xml = xml.trim();
		String encoding = "UTF-8";

		try {
			String xmlHeader = xml.substring(xml.indexOf(""));
			if (xmlHeader.contains(" encoding")) {
				encoding = xmlHeader.substring(xmlHeader.indexOf(" encoding") + " encoding".length());
				encoding = encoding.substring(encoding.indexOf("=") + 1);
				while (encoding.substring(0, 1).equals(" ")) {
					encoding = encoding.substring(1);
				}

				String firstChar = encoding.substring(0, 1);
				if (firstChar.equals("\"") || firstChar.equals("'")) {
					encoding = encoding.substring(1);
					encoding = encoding.substring(0, encoding.indexOf(firstChar)).trim();
				} else {
					encoding = encoding.substring(0, encoding.indexOf(" ")).trim();
				}

			}
		} catch (Exception e) {
		}

		return createDocument(xml, encoding);
	}

	public static Document createDocument(String xml, String charsetName) {
		xml = xml.trim();
		try {
			return createDocument(new ByteArrayInputStream(xml.getBytes(charsetName)));
		} catch (Exception e) {
			// e.printStackTrace();
			return createDocument(new ByteArrayInputStream(xml.getBytes()));
		}
	}

	// **************************************************************************
	// ** createDocument
	// **************************************************************************
	/** Used to create a DOM document from an InputStream. */

	public static Document createDocument(InputStream is) {
		try {
			DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
			DocumentBuilder builder = builderFactory.newDocumentBuilder();
			return builder.parse(is);
		} catch (Exception e) {
			// e.printStackTrace();
			return null;
		}
	}

	// **************************************************************************
	// ** getOuterNode
	// **************************************************************************
	/**
	 * Returns the outer node for a given xml document.
	 * 
	 * @param xml
	 *            A org.w3c.dom.Document
	 */
	public static Node getOuterNode(Document xml) {
		if (xml == null)
			return null;
		NodeList OuterNodes = xml.getChildNodes();
		for (int i = 0; i < OuterNodes.getLength(); i++) {
			if (OuterNodes.item(i).getNodeType() == 1) {
				return OuterNodes.item(i);
			}
		}
		return null;
	}

	// **************************************************************************
	// ** equals
	// **************************************************************************
	/**
	 * Used to compare two XML documents by performing a raw string comparison.
	 */
	public static boolean equals(Document xml, Document xml2) {
		if (xml == null && xml2 == null)
			return true;
		if (xml != null && xml2 == null)
			return false;
		if (xml == null && xml2 != null)
			return false;
		return getText(xml).equals(getText(xml2));
	}

	// **************************************************************************
	// ** getText
	// **************************************************************************
	/**
	 * Converts a DOM Document to a String
	 * 
	 * @param xml
	 *            A org.w3c.dom.Document
	 */
	public static String getText(Document xml) {

		try {
			TransformerFactory factory = TransformerFactory.newInstance();
			Transformer transformer = factory.newTransformer();
			DOMSource source = new DOMSource(xml);
			ByteArrayOutputStream bas = new ByteArrayOutputStream();
			StreamResult result = new StreamResult(bas);
			transformer.transform(source, result);
			String encoding = xml.getXmlEncoding();
			if (encoding != null)
				return bas.toString(encoding);
			else
				return bas.toString();
		} catch (Exception e) {
			// System.out.println(e.toString());
			return "";
		}
	}

	// **************************************************************************
	// ** getText
	// **************************************************************************
	/** Converts a NodeList to a String */

	public static String getText(NodeList nodeList) {
		StringBuffer ret = new StringBuffer();
		for (int i = 0; i < nodeList.getLength(); i++) {
			ret.append(getText(nodeList.item(i)));
		}
		return ret.toString();
	}

	// **************************************************************************
	// ** getText
	// **************************************************************************
	/** Converts a Node to a String */

	public static String getText(Node node) {
		StringBuffer ret = new StringBuffer();
		if (node.getNodeType() == 1) {

			if (hasChildren(node)) {
				ret.append(getNodeValue(node));
			} else {
				ret.append("<" + node.getNodeName() + getAttributes(node) + ">");
				ret.append(getNodeValue(node));
				ret.append("");
			}
		}
		return ret.toString();
	}

	// **************************************************************************
	// ** getAttributes
	// **************************************************************************
	/** Used to retrieve all of the attributes for a given node. */

	private static String getAttributes(Node node) {
		if (node == null)
			return "";
		NamedNodeMap attr = node.getAttributes();
		String Attributes = "";
		if (attr != null) {
			for (int j = 0; j < attr.getLength(); j++) {
				String name = attr.item(j).getNodeName();
				String value = attr.item(j).getTextContent();
				if (value == null)
					value = attr.item(j).getNodeValue();
				if (value == null)
					value = "";
				// System.out.println(name + "=" + attr.item(j).getNodeValue());
				Attributes += " " + name + "=\"" + value + "\"";
			}
		}
		return Attributes;
	}

	// **************************************************************************
	// ** hasChildren
	// **************************************************************************
	/**
	 * Used to determine whether a given node has any children. Differs from the
	 * native DOM implementation in that this function only considers child
	 * nodes that have a node type value equal to 1.
	 */
	public static boolean hasChildren(Node node) {

		NodeList nodeList = node.getChildNodes();
		for (int i = 0; i < nodeList.getLength(); i++) {
			if (nodeList.item(i).getNodeType() == 1) {
				return true;
			}
		}
		return false;
	}

	// **************************************************************************
	// ** getAttributeValue
	// **************************************************************************
	/**
	 * Used to return the value of a given node attribute. The search is case
	 * insensitive. If no match is found, returns an empty string.
	 */
	public static String getAttributeValue(NamedNodeMap attrCollection, String attrName) {

		if (attrCollection != null) {
			for (int i = 0; i < attrCollection.getLength(); i++) {
				Node node = attrCollection.item(i);
				if (node.getNodeName().equalsIgnoreCase(attrName)) {
					return node.getNodeValue();
				}
			}
		}
		return "";
	}

	// **************************************************************************
	// ** getAttributeValue
	// **************************************************************************
	/**
	 * Used to return the value of a given node attribute. The search is case
	 * insensitive. If no match is found, returns an empty string.
	 */
	public static String getAttributeValue(Node node, String attrName) {
		return getAttributeValue(node.getAttributes(), attrName);
	}

	// **************************************************************************
	// ** setAttributeValue
	// **************************************************************************
	/**
	 * Used to create or update an attribute.
	 */
	public static void setAttributeValue(Node node, String attrName, String attrValue) {

		if (node == null)
			return;

		try {
			((Element) node).setAttribute(attrName, attrValue);
		} catch (Exception e) {

			// Apparently some nodes can't be cast to an Element so we can try
			// to update the node's attribute collection.
			try {

				NamedNodeMap attrCollection = node.getAttributes();
				for (int i = 0; i < attrCollection.getLength(); i++) {
					org.w3c.dom.Node attribute = attrCollection.item(i);
					if (attribute.getNodeName().equals(attrName)) {
						attribute.setNodeValue(attrValue);
						return;
					}
				}

				// TODO: If we're still here, create new attribute
			} catch (Exception ex) {
			}
		}
	}

	// **************************************************************************
	// ** getNodeValue
	// **************************************************************************
	/**
	 * Returns the value of a given node as text. If the node has children, the
	 * method will return an xml fragment which will include the input node as
	 * the outer node. This is a legacy feature which should be deprecated over
	 * time.
	 */
	public static String getNodeValue(Node node) {

		String nodeValue = "";

		if (hasChildren(node)) {

			StringBuffer xmlTree = new StringBuffer();
			traverse(node, xmlTree);
			nodeValue = xmlTree.toString();

		} else {
			nodeValue = node.getTextContent();
		}

		if (nodeValue == null) {
			return "";
		} else {
			return nodeValue;
		}
	}

	private static void traverse(Node tree, StringBuffer xmlTree) {
		if (tree.getNodeType() == 1) {
			String Attributes = getAttributes(tree);
			xmlTree.append("<" + tree.getNodeName() + Attributes + ">");
			if (hasChildren(tree)) {

				NodeList xmlNodeList = tree.getChildNodes();
				for (int i = 0; i < xmlNodeList.getLength(); i++) {
					traverse(xmlNodeList.item(i), xmlTree);
				}

			} else {

				String nodeValue = tree.getTextContent();
				if (nodeValue == null) {
					nodeValue = "";
				}

				xmlTree.append(nodeValue);
			}

			xmlTree.append("");
		}
	}

	// **************************************************************************
	// ** getDocumentAttributes
	// **************************************************************************
	/**
	 * @param xml
	 *            A org.w3c.dom.Document
	 */
	public static NamedNodeMap getDocumentAttributes(Document xml) {
		NodeList Definitions = xml.getChildNodes();
		for (int i = 0; i < Definitions.getLength(); i++) {
			if (Definitions.item(i).getNodeType() == 1) {
				return Definitions.item(i).getAttributes();
			}
		}
		return null;
	}

	// **************************************************************************
	// ** getTargetNameSpace
	// **************************************************************************
	/**
	 * Returns the "targetNamespace" for a given xml document.
	 * 
	 * @param xml
	 *            A org.w3c.dom.Document
	 */
	public static String getTargetNameSpace(Document xml) {
		NamedNodeMap attr = getDocumentAttributes(xml);
		return getAttributeValue(attr, "targetNamespace");
	}

	// **************************************************************************
	// ** getNameSpaces
	// **************************************************************************
	/**
	 * Returns a hashmap with all the namespaces found in a given xml document.
	 * The hashmap key is the namespace prefix and the corresponding value is
	 * the namespace url.
	 *
	 * @param xml
	 *            A org.w3c.dom.Document
	 */
	public static java.util.HashMap getNameSpaces(Document xml) {
		java.util.HashMap namespaces = new java.util.HashMap();
		getNameSpaces(getOuterNode(xml), namespaces);
		return namespaces;
	}

	private static void getNameSpaces(Node node, java.util.HashMap namespaces) {
		if (node.getNodeType() == 1) {

			NamedNodeMap attr = node.getAttributes();
			if (attr != null) {
				for (int j = 0; j < attr.getLength(); j++) {
					String name = attr.item(j).getNodeName();
					String value = attr.item(j).getTextContent();
					if (name.startsWith("xmlns:")) {
						name = name.substring(6);
						namespaces.put(name, value);
					}
				}
			}

			if (hasChildren(node)) {
				NodeList childNodes = node.getChildNodes();
				for (int i = 0; i < childNodes.getLength(); i++) {
					getNameSpaces(childNodes.item(i), namespaces);
				}
			}

		}
	}

	// **************************************************************************
	// ** getElementsByTagName
	// **************************************************************************
	/**
	 * Returns an array of nodes that match a given tagName (node name). The
	 * results will include all nodes that match, regardless of namespace. To
	 * narrow the results to a specific namespace, simply include the namespace
	 * prefix in the tag name (e.g. "t:Contact").
	 */
	public static org.w3c.dom.Node[] getElementsByTagName(String tagName, Document xml) {
		return getElementsByTagName(tagName, getOuterNode(xml));
	}

	// **************************************************************************
	// ** getElementsByTagName
	// **************************************************************************
	/**
	 * Returns an array of nodes that match a given tagName (node name). The
	 * results will include all nodes that match, regardless of namespace. To
	 * narrow the results to a specific namespace, simply include the namespace
	 * prefix in the tag name (e.g. "t:Contact"). Returns an empty array if no
	 * nodes are found.
	 */
	public static org.w3c.dom.Node[] getElementsByTagName(String tagName, Node node) {
		java.util.ArrayList nodes = new java.util.ArrayList();
		getElementsByTagName(tagName, node, nodes);
		return nodes.toArray(new org.w3c.dom.Node[nodes.size()]);
	}

	private static void getElementsByTagName(String tagName, Node node, java.util.ArrayList nodes) {
		if (node != null && node.getNodeType() == 1) {

			String nodeName = node.getNodeName().trim();
			if (nodeName.contains(":") && !tagName.contains(":")) {
				nodeName = nodeName.substring(nodeName.indexOf(":") + 1);
			}

			if (nodeName.equalsIgnoreCase(tagName)) {
				nodes.add(node);
			}

			if (hasChildren(node)) {
				NodeList childNodes = node.getChildNodes();
				for (int i = 0; i < childNodes.getLength(); i++) {
					getElementsByTagName(tagName, childNodes.item(i), nodes);
				}
			}

		}
	}

	/** Converts a NodeList into an array to simplify nested loops. */
	public static Node[] getNodes(NodeList nodeList) {
		java.util.ArrayList nodes = new java.util.ArrayList();
		for (int i = 0; i < nodeList.getLength(); i++) {
			Node node = nodeList.item(i);
			if (node.getNodeType() == 1)
				nodes.add(node);
		}
		return nodes.toArray(new Node[nodes.size()]);
	}

	public final static String ESCAPE_CHARS = "<>&\"\'";
	public final static java.util.List ESCAPE_STRINGS = java.util.Collections
	        .unmodifiableList(java.util.Arrays.asList(new String[] { "<", ">", "&", """, "'" }));

	private static String UNICODE_LOW = "" + ((char) 0x20); // space
	private static String UNICODE_HIGH = "" + ((char) 0x7f);

	// **************************************************************************
	// ** escapeXml
	// **************************************************************************
	/**
	 * Used to encode text data for use in an XML tag or attribute.
	 */
	public static String escapeXml(String content) {
		String result = content;

		if ((content != null) && (content.length() > 0)) {
			boolean modified = false;
			StringBuilder stringBuilder = new StringBuilder(content.length());
			for (int i = 0, count = content.length(); i < count; ++i) {
				String character = content.substring(i, i + 1);
				int pos = ESCAPE_CHARS.indexOf(character);
				if (pos > -1) {
					stringBuilder.append(ESCAPE_STRINGS.get(pos));
					modified = true;
				} else {
					if ((character.compareTo(UNICODE_LOW) > -1) && (character.compareTo(UNICODE_HIGH) < 1)) {
						stringBuilder.append(character);
					} else {
						stringBuilder.append("&#" + ((int) character.charAt(0)) + ";");
						modified = true;
					}
				}
			}
			if (modified) {
				result = stringBuilder.toString();
			}
		}

		return result;
	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy