001/*
002 *                    BioJava development code
003 *
004 * This code may be freely distributed and modified under the
005 * terms of the GNU Lesser General Public Licence.  This should
006 * be distributed with the code.  If you do not have a copy,
007 * see:
008 *
009 *      http://www.gnu.org/copyleft/lesser.html
010 *
011 * Copyright for this code is held jointly by the individual
012 * authors.  These should be listed in @author doc comments.
013 *
014 * For more information on the BioJava project and its aims,
015 * or to join the biojava-l mailing list, visit the home page
016 * at:
017 *
018 *      http://www.biojava.org/
019 *
020 */
021package org.biojava.nbio.core.util;
022
023import org.w3c.dom.Document;
024import org.w3c.dom.Element;
025import org.w3c.dom.Node;
026import org.w3c.dom.NodeList;
027import org.xml.sax.SAXException;
028
029import javax.xml.parsers.DocumentBuilder;
030import javax.xml.parsers.DocumentBuilderFactory;
031import javax.xml.parsers.ParserConfigurationException;
032import javax.xml.transform.Transformer;
033import javax.xml.transform.TransformerException;
034import javax.xml.transform.TransformerFactory;
035import javax.xml.transform.dom.DOMSource;
036import javax.xml.transform.stream.StreamResult;
037import javax.xml.xpath.XPath;
038import javax.xml.xpath.XPathConstants;
039import javax.xml.xpath.XPathExpressionException;
040import javax.xml.xpath.XPathFactory;
041import java.io.*;
042import java.util.ArrayList;
043
044import static org.biojava.nbio.core.sequence.io.util.IOUtils.close;
045import static org.biojava.nbio.core.sequence.io.util.IOUtils.openFile;
046
047/**
048 *
049 * @author Scooter
050 */
051public class XMLHelper {
052
053        static public Element addChildElement(Element parentElement, String elementName) {
054                Element childElement = parentElement.getOwnerDocument().createElement(elementName);
055                parentElement.appendChild(childElement);
056                return childElement;
057        }
058
059        static public Document getNewDocument() throws ParserConfigurationException  {
060
061                //Create instance of DocumentBuilderFactory
062                DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
063                //Get the DocumentBuilder
064                DocumentBuilder docBuilder = factory.newDocumentBuilder();
065                //Create blank DOM Document
066                Document doc = docBuilder.newDocument();
067                return doc;
068        }
069
070        static public Document loadXML(String fileName) throws SAXException, IOException, ParserConfigurationException  {
071                InputStream is = openFile(new File(fileName));
072                Document doc = inputStreamToDocument(new BufferedInputStream(is));
073                close(is);
074                return doc;
075        }
076
077        static public Document inputStreamToDocument(InputStream inputStream) throws SAXException, IOException, ParserConfigurationException  {
078                DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
079
080                DocumentBuilder db = dbf.newDocumentBuilder();
081
082                Document doc = db.parse(inputStream);
083                doc.getDocumentElement().normalize();
084
085                return doc;
086        }
087
088        static public void outputToStream(Document document, OutputStream outputStream) throws TransformerException {
089                // Use a Transformer for output
090                TransformerFactory tFactory = TransformerFactory.newInstance();
091                Transformer transformer = tFactory.newTransformer();
092                //    transformer.setOutputProperty(OutputKeys.INDENT, "yes");
093
094                DOMSource source = new DOMSource(document);
095                StreamResult result = new StreamResult(outputStream);
096                transformer.transform(source, result);
097
098
099        }
100
101        static public void outputToStream(Element document, OutputStream outputStream) throws TransformerException  {
102                // Use a Transformer for output
103                TransformerFactory tFactory = TransformerFactory.newInstance();
104                Transformer transformer = tFactory.newTransformer();
105                //     transformer.setOutputProperty(OutputKeys.INDENT, "yes");
106
107                DOMSource source = new DOMSource(document);
108                StreamResult result = new StreamResult(outputStream);
109                transformer.transform(source, result);
110
111        }
112        //static XPath xpath = XPathFactory.newInstance().newXPath();
113
114        static public Element selectParentElement(Element element, String parentName) {
115                Element parentElement = (Element) element.getParentNode();
116                if (parentElement == null) {
117                        return null;
118                }
119                if (parentElement.getTagName().equals(parentName)) {
120                        return parentElement;
121                }
122                return selectParentElement(parentElement, parentName);
123        }
124
125        static public Element selectSingleElement(Element element, String xpathExpression) throws XPathExpressionException {
126                if (xpathExpression.indexOf("/") == -1) {
127                        NodeList nodeList = element.getChildNodes();
128                        for (int i = 0; i < nodeList.getLength(); i++) {
129                                Node node = nodeList.item(i);
130                                if (node.getNodeType() == Node.ELEMENT_NODE && node.getNodeName().equals(xpathExpression)) {
131                                        return (Element) node;
132                                }
133                        }
134                        //  NodeList nodes = element.getElementsByTagName(xpathExpression);
135                        //  if (nodes.getLength() > 0) {
136                        //      return (Element) nodes.item(0);
137                        //  } else {
138                        return null;
139                        //  }
140                } else {
141                        XPath xpath = XPathFactory.newInstance().newXPath();
142                        Element node = (Element) xpath.evaluate(xpathExpression, element, XPathConstants.NODE);
143                        return node;
144                }
145        }
146
147        static public ArrayList<Element> selectElements(Element element, String xpathExpression) throws XPathExpressionException {
148                ArrayList<Element> resultVector = new ArrayList<Element>();
149                if (element == null) {
150                        return resultVector;
151                }
152                if (xpathExpression.indexOf("/") == -1) {
153                        NodeList nodeList = element.getChildNodes();
154                        for (int i = 0; i < nodeList.getLength(); i++) {
155                                Node node = nodeList.item(i);
156                                if (node.getNodeType() == Node.ELEMENT_NODE && node.getNodeName().equals(xpathExpression)) {
157                                        resultVector.add((Element) node);
158                                }
159                        }
160                } else {
161                        XPath xpath = XPathFactory.newInstance().newXPath();
162                        NodeList nodes = (NodeList) xpath.evaluate(xpathExpression, element, XPathConstants.NODESET);
163
164
165                        for (int i = 0; i < nodes.getLength(); i++) {
166                                Node node = nodes.item(i);
167                                resultVector.add((Element) node);
168                        }
169                }
170                return resultVector;
171        }
172}