/* * Copyright 2013, 2014 Deutsche Nationalbibliothek * * Licensed 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.culturegraph.mf.commons; import static java.util.stream.Collectors.joining; import java.io.StringWriter; import javax.xml.transform.OutputKeys; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import org.w3c.dom.Node; import org.w3c.dom.NodeList; /** * @author Christoph Böhme <c.boehme@dnb.de> * */ public final class XmlUtil { private static final String APPLICATION_XML_MIME_TYPE = "application/xml"; private static final String TEXT_XML_MIME_TYPE = "text/xml"; private static final String XML_BASE_MIME_TYPE = "+xml"; private XmlUtil() { // No instances allowed } public static String nodeToString(final Node node) { return nodeToString(node, false); } public static String nodeToString(final Node node, final boolean omitXMLDecl) { final StringWriter writer = new StringWriter(); final Transformer transformer; try { transformer = TransformerFactory.newInstance().newTransformer(); } catch (final TransformerException e) { throw new AssertionError( "No errors expected when creating an identity transformer", e); } if (omitXMLDecl) { transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes"); } else { transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no"); } try { transformer.transform(new DOMSource(node), new StreamResult(writer)); } catch (final TransformerException e) { throw new AssertionError( "No errors expected during identity transformation", e); } return writer.toString(); } public static String nodeListToString(final NodeList nodes) { final StringBuilder builder = new StringBuilder(); for (int i=0; i < nodes.getLength(); ++i) { builder.append(nodeToString(nodes.item(i), i != 0)); } return builder.toString(); } public static boolean isXmlMimeType(final String mimeType) { if (mimeType == null) { return false; } return APPLICATION_XML_MIME_TYPE.equals(mimeType) || TEXT_XML_MIME_TYPE.equals(mimeType) || mimeType.endsWith(XML_BASE_MIME_TYPE); } public static String escape(String unescaped) { return unescaped.chars() .mapToObj(XmlUtil::escapeChar) .collect(joining()); } private static String escapeChar(int ch) { final String entity = entityFor(ch); if (entity != null) { return entity; } if (ch > 0x7f) { return "&#" + Integer.toString(ch) + ";"; } return Character.toString((char) ch); } private static String entityFor(int ch) { switch (ch) { case '<': return "<"; case '>': return ">"; case '&': return "&"; case '"': return """; case '\'': return "'"; default: return null; } } }