Java tutorial
//package com.java2s; /*--------------------------------------------------------------- * Copyright 2005 by the Radiological Society of North America * * This source software is released under the terms of the * RSNA Public License (http://mirc.rsna.org/rsnapubliclicense) *----------------------------------------------------------------*/ import java.io.*; import javax.xml.transform.Source; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import javax.xml.transform.stream.StreamSource; 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; public class Main { /** * Transform an XML file using an XSL file and an array of parameters. * The parameter array consists of a sequence of pairs of (String parametername) * followed by (Object parametervalue) in an Object[]. * @param doc the document to transform. * @param xsl the XSL transformation program. * @param params the array of transformation parameters. * @return the transformed text. */ public static String getTransformedText(File doc, File xsl, Object[] params) throws Exception { return getTransformedText(new StreamSource(doc), new StreamSource(xsl), params); } /** * Transform an XML DOM Document using an XSL file and an array of parameters. * The parameter array consists of a sequence of pairs of (String parametername) * followed by (Object parametervalue) in an Object[]. * @param doc the document to transform. * @param xsl the XSL transformation program. * @param params the array of transformation parameters. * @return the transformed text. */ public static String getTransformedText(Document doc, File xsl, Object[] params) throws Exception { return getTransformedText(new DOMSource(doc), new StreamSource(xsl), params); } /** * Transform an XML document using an XSL DOM document and an array of parameters. * The parameter array consists of a sequence of pairs of (String parametername) * followed by (Object parametervalue) in an Object[]. * @param doc the document to transform. * @param xsl the XSL transformation program. * @param params the array of transformation parameters. * @return the transformed text. */ public static String getTransformedText(Document doc, Document xsl, Object[] params) throws Exception { return getTransformedText(new DOMSource(doc), new DOMSource(xsl), params); } /** * General method for transformation to text. Transform a Source * document using a Source XSL document and an array of parameters. * The parameter array consists of a sequence of pairs of (String parametername) * followed by (Object parametervalue) in an Object[]. * @param doc the document to transform. * @param xsl the XSL transformation program. * @param params the array of transformation parameters. * @return the transformed text. */ public static String getTransformedText(Source doc, Source xsl, Object[] params) throws Exception { TransformerFactory tFactory = TransformerFactory.newInstance(); Transformer transformer = tFactory.newTransformer(xsl); if ((params != null) && (params.length > 1)) { for (int i = 0; i < params.length; i = i + 2) { transformer.setParameter((String) params[i], params[i + 1]); } } StringWriter sw = new StringWriter(); transformer.transform(doc, new StreamResult(sw)); return sw.toString(); } /** * Make a String from an XML DOM Node. * @param node the node at the top of the tree. * @return the XML string for the node and its children. * If the node is a DOCUMENT_NODE, the string includes * an XML declaration specifying an encoding of UTF-8. */ public static String toString(Node node) { StringBuffer sb = new StringBuffer(); renderNode(sb, node); return sb.toString(); } private static void renderNode(StringBuffer sb, Node node) { if (node == null) { sb.append("null"); return; } switch (node.getNodeType()) { case Node.DOCUMENT_NODE: sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"); Node root = ((Document) node).getDocumentElement(); renderNode(sb, root); break; case Node.ELEMENT_NODE: String name = getNodeNameWithNamespace(node); NamedNodeMap attributes = node.getAttributes(); if (attributes.getLength() == 0) { sb.append("<" + name + ">"); } else { sb.append("<" + name + " "); int attrlen = attributes.getLength(); for (int i = 0; i < attrlen; i++) { Node attr = attributes.item(i); String attrName = getNodeNameWithNamespace(attr); sb.append(attrName + "=\"" + escapeChars(attr.getNodeValue())); if (i < attrlen - 1) sb.append("\" "); else sb.append("\">"); } } NodeList children = node.getChildNodes(); if (children != null) { for (int i = 0; i < children.getLength(); i++) { renderNode(sb, children.item(i)); } } sb.append("</" + name + ">"); break; case Node.TEXT_NODE: sb.append(escapeChars(node.getNodeValue())); break; case Node.CDATA_SECTION_NODE: sb.append("<![CDATA[" + node.getNodeValue() + "]]>"); break; case Node.PROCESSING_INSTRUCTION_NODE: sb.append("<?" + node.getNodeName() + " " + escapeChars(node.getNodeValue()) + "?>"); break; case Node.ENTITY_REFERENCE_NODE: sb.append("&" + node.getNodeName() + ";"); break; case Node.DOCUMENT_TYPE_NODE: // Ignore document type nodes break; case Node.COMMENT_NODE: sb.append("<!--" + node.getNodeValue() + "-->"); break; } return; } private static void renderNode(StringBuffer sb, Node node, String margin, String indent, String lab, String rab, String nl) { if (node == null) { sb.append("null"); return; } switch (node.getNodeType()) { case Node.DOCUMENT_NODE: //sb.append(margin + lab +"?xml version=\"1.0\" encoding=\"UTF-8\"?" + rab + nl); Node root = ((Document) node).getDocumentElement(); renderNode(sb, root, margin, indent, lab, rab, nl); break; case Node.ELEMENT_NODE: String name = getNodeNameWithNamespace(node); NodeList children = node.getChildNodes(); int nChildren = children.getLength(); NamedNodeMap attributes = node.getAttributes(); int nAttrs = attributes.getLength(); boolean singleShortTextChild = (nAttrs == 0) && (nChildren == 1) && (children.item(0).getNodeType() == Node.TEXT_NODE) && (children.item(0).getTextContent().length() < 70) && (!children.item(0).getTextContent().contains("\n")); if (singleShortTextChild) { sb.append(margin + lab + name + ((nChildren == 0) ? "/" : "") + rab); } else if (nAttrs == 0 && !singleShortTextChild) { sb.append(margin + lab + name + ((nChildren == 0) ? "/" : "") + rab + nl); } else if (nAttrs == 1) { Node attr = attributes.item(0); String attrName = getNodeNameWithNamespace(attr); sb.append(margin + lab + name + " " + attrName + "=\"" + escapeChars(attr.getNodeValue()) + "\"" + ((nChildren == 0) ? "/" : "") + rab + nl); } else { sb.append(margin + lab + name + nl); for (int i = 0; i < nAttrs; i++) { Node attr = attributes.item(i); String attrName = getNodeNameWithNamespace(attr); sb.append(margin + indent + attrName + "=\"" + escapeChars(attr.getNodeValue())); if (i < nAttrs - 1) sb.append("\"" + nl); else sb.append("\"" + ((nChildren == 0) ? "/" : "") + rab + nl); } } if (singleShortTextChild) { String text = escapeChars(node.getTextContent()); sb.append(text.trim()); sb.append(lab + "/" + name + rab + nl); } else { for (int i = 0; i < nChildren; i++) { renderNode(sb, children.item(i), margin + indent, indent, lab, rab, nl); } } if (nChildren != 0 && !singleShortTextChild) sb.append(margin + lab + "/" + name + rab + nl); break; case Node.TEXT_NODE: String text = escapeChars(node.getNodeValue()); String[] lines = text.split("\n"); for (String line : lines) { line = line.trim(); if (!line.equals("")) sb.append(margin + line + nl); } break; case Node.CDATA_SECTION_NODE: String cdataText = node.getNodeValue(); String[] cdataLines = cdataText.split("\n"); sb.append(margin + lab + "![CDATA[" + nl); for (String line : cdataLines) { line = line.trim(); if (!line.equals("")) sb.append(margin + indent + line + nl); } sb.append(margin + "]]" + rab + nl); break; case Node.PROCESSING_INSTRUCTION_NODE: sb.append(margin + lab + "?" + node.getNodeName() + " " + escapeChars(node.getNodeValue()) + "?" + rab + nl); break; case Node.ENTITY_REFERENCE_NODE: sb.append("&" + node.getNodeName() + ";"); break; case Node.DOCUMENT_TYPE_NODE: // Ignore document type nodes break; case Node.COMMENT_NODE: sb.append(margin + lab + "!--" + node.getNodeValue() + "--" + rab + nl); break; } return; } private static String getNodeNameWithNamespace(Node node) { String name = node.getNodeName(); String ns = node.getNamespaceURI(); String prefix = (ns != null) ? node.lookupPrefix(ns) : null; if ((prefix != null) && !name.startsWith(prefix + ":")) { name = prefix + ":" + name; } return name; } /** * Escape the ampersand, less-than, greater-than, single and double quote * characters in a string, replacing with their XML entities. * @param theString the string to escape. * @return the modified string. */ public static String escapeChars(String theString) { return theString.replace("&", "&").replace(">", ">").replace("<", "<").replace("\"", """) .replace("'", "'"); } /** * Get the text content of an element identified by a path, * where the path elements can include an index. The first * path element must not have an index, and its name must * match the name of the starting node. If the starting * node is a Document, the root Element of the document is * used as the starting point. Path elements must be separated * by the slash character. If the path starts with a slash, * the slash is ignored. If the element or attribute identified * by the path is not present as a child of the starting node, * the empty string is returned. If a path element identifies * an attribute, any subsequent path elements are ignored. * A path is in the form: /e1/e2/e3/... or /e1/e2/@attr * Note the slash preceding the attribute's @-sign. * @param node the starting node for the path. The first path * element must match the name of this node. * @param path the path to the target node. * @return the full text value of the target node (including all * descendent text nodes), or the empty string if the target is * not a descendent of the starting node. */ public static String getTextContent(Node node, String path) { if (node instanceof Document) node = ((Document) node).getDocumentElement(); if (!(node instanceof Element)) return ""; Element el = (Element) node; path = path.replaceAll("\\s", ""); if (path.startsWith("/")) path = path.substring(1); String[] pathElements = path.split("/"); if (!pathElements[0].equals(el.getTagName())) return ""; for (int i = 1; i < pathElements.length; i++) { String pe = pathElements[i]; if (pe.startsWith("@")) { //If this path element identifies an attribute, return it //and ignore any further path elements. return el.getAttribute(pe.substring(1)); } else { //This path element identifies an Element. It may have an index. //Get the index, if present, and get the element name. int n = 0; int k = pe.indexOf("["); int kk = pe.lastIndexOf("]"); if ((k != -1) && (k < kk)) { try { n = Integer.parseInt(pe.substring(k + 1, kk)); } catch (Exception ex) { return ""; } pe = pe.substring(0, k); } else if (k != kk) return ""; //We now have the element name and the index. //Find the identified Element. We have to count //matching elements to find the one identified //by the index. int nn = 0; Node child = el.getFirstChild(); while (child != null) { if ((child.getNodeType() == Node.ELEMENT_NODE) && child.getNodeName().equals(pe)) { if (n == nn) break; nn++; } child = child.getNextSibling(); } //If the child is null, we didn't find the identified Element. if (child == null) return ""; //If we get here, we found it, now look for the next one. el = (Element) child; } } //Okay, we must be at the end of the path, and it must be an Element. //Return the text content of the element. return el.getTextContent(); } }