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

org.apache.xml.serializer.ToXMLStream Maven / Gradle / Ivy

Go to download

Tool to convert CSV and XLS to XML, to transform XML and to convert XML to CSV, HTML, other text files, PDF etc., useful as command line tool and integrated in other projects.

There is a newer version: 3.119
Show newest version
/*
 * 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.
 */
/*
 * $Id: ToXMLStream.java 469359 2006-10-31 03:43:19Z minchau $
 */

package org.apache.xml.serializer;

import java.io.IOException;

import javax.xml.transform.ErrorListener;
import javax.xml.transform.Result;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;

import org.apache.xml.serializer.utils.MsgKey;
import org.apache.xml.serializer.utils.Utils;
import org.xml.sax.SAXException;

import com.sta.mlogger.MLogger;

/**
 * 

Name: ToXMLStream

*

Description: Klasse wg. Zeilenumbruch-Bug ersetzt. *

*

Comment: ... * This class converts SAX or SAX-like calls to a serialized xml document. The xsl:output method is "xml". * This class is used explicitly in code generated by XSLTC, so it is "public", but it should * be viewed as internal or package private, this is not an API. * _xsl.usage internal *

*

Copyright: Copyright (c) 2019, 2021

*

Company: >StA-Soft<

* @author StA * @version 1.0 */ public class ToXMLStream extends ToStream { /** * Map that tells which XML characters should have special treatment, and it * provides character to entity name lookup. */ private CharInfo m_xmlcharInfo = CharInfo.getCharInfo(CharInfo.XML_ENTITIES_RESOURCE, Method.XML); /** * Default constructor. */ public ToXMLStream() { m_charInfo = m_xmlcharInfo; initCDATA(); // initialize namespaces m_prefixMap = new NamespaceMappings(); } /** * Copy properties from another SerializerToXML. * @param xmlListener non-null reference to a SerializerToXML object. */ public void copyFrom(ToXMLStream xmlListener) { setWriter(xmlListener.m_writer); // m_outputStream = xmlListener.m_outputStream; String encoding = xmlListener.getEncoding(); setEncoding(encoding); setOmitXMLDeclaration(xmlListener.getOmitXMLDeclaration()); m_ispreserve = xmlListener.m_ispreserve; m_preserves = xmlListener.m_preserves; m_isprevtext = xmlListener.m_isprevtext; m_doIndent = xmlListener.m_doIndent; setIndentAmount(xmlListener.getIndentAmount()); m_startNewLine = xmlListener.m_startNewLine; m_needToOutputDocTypeDecl = xmlListener.m_needToOutputDocTypeDecl; setDoctypeSystem(xmlListener.getDoctypeSystem()); setDoctypePublic(xmlListener.getDoctypePublic()); setStandalone(xmlListener.getStandalone()); setMediaType(xmlListener.getMediaType()); m_encodingInfo = xmlListener.m_encodingInfo; m_spaceBeforeClose = xmlListener.m_spaceBeforeClose; m_cdataStartCalled = xmlListener.m_cdataStartCalled; } @Override public void startDocumentInternal() throws org.xml.sax.SAXException { if (m_needToCallStartDocument) { super.startDocumentInternal(); m_needToCallStartDocument = false; if (m_inEntityRef) { return; } m_needToOutputDocTypeDecl = true; m_startNewLine = false; /* The call to getXMLVersion() might emit an error message * and we should emit this message regardless of if we are * writing out an XML header or not. */ final String version = getXMLVersion(); if (!getOmitXMLDeclaration()) { String encoding = Encodings.getMimeEncoding(getEncoding()); String standalone; if (m_standaloneWasSpecified) { standalone = " standalone=\"" + getStandalone() + "\""; } else { standalone = ""; } try { final java.io.Writer writer = m_writer; writer.write(""); if (m_doIndent) { // if (m_standaloneWasSpecified || (getDoctypePublic() != null) || (getDoctypeSystem() != null) || true) // { // We almost never put a newline after the XML // header because this XML could be used as // an extenal general parsed entity // and we don't know the context into which it // will be used in the future. Only when // standalone, or a doctype system or public is // specified are we free to insert a new line // after the header. Is it even worth bothering // in these rare cases? writer.write(m_lineSep, 0, m_lineSepLen); // } } } catch (IOException e) { throw new SAXException(e); } } } } @Override public void endDocument() throws org.xml.sax.SAXException { flushPending(); if (m_doIndent && !m_isprevtext) { try { outputLineSep(); } catch (IOException e) { throw new SAXException(e); } } flushWriter(); if (m_tracer != null) { super.fireEndDoc(); } } /** * Starts a whitespace preserving section. All characters printed * within a preserving section are printed without indentation and * without consolidating multiple spaces. This is equivalent to * the xml:space="preserve" attribute. Only XML * and HTML serializers need to support this method. *

* The contents of the whitespace preserving section will be delivered * through the regular characters event. * @throws org.xml.sax.SAXException in case of an error */ public void startPreserving() throws org.xml.sax.SAXException { // Not sure this is really what we want. -sb m_preserves.push(true); m_ispreserve = true; } /** * Ends a whitespace preserving section. * @throws org.xml.sax.SAXException in case of an error * @see #startPreserving */ public void endPreserving() throws org.xml.sax.SAXException { // Not sure this is really what we want. -sb m_ispreserve = m_preserves.isEmpty() ? false : m_preserves.pop(); } @Override public void processingInstruction(String target, String data) throws org.xml.sax.SAXException { if (m_inEntityRef) { return; } flushPending(); if (target.equals(Result.PI_DISABLE_OUTPUT_ESCAPING)) { startNonEscaping(); } else if (target.equals(Result.PI_ENABLE_OUTPUT_ESCAPING)) { endNonEscaping(); } else { try { if (m_elemContext.m_startTagOpen) { closeStartTag(); m_elemContext.m_startTagOpen = false; } else if (m_needToCallStartDocument) { startDocumentInternal(); } if (shouldIndent()) { indent(); } final java.io.Writer writer = m_writer; writer.write(" 0) && !Character.isSpaceChar(data.charAt(0))) { writer.write(' '); } int indexOfQLT = data.indexOf("?>"); if (indexOfQLT >= 0) { // See XSLT spec on error recovery of "?>" in PIs. if (indexOfQLT > 0) { writer.write(data.substring(0, indexOfQLT)); } writer.write("? >"); // add space between. if ((indexOfQLT + 2) < data.length()) { writer.write(data.substring(indexOfQLT + 2)); } } else { writer.write(data); } writer.write('?'); writer.write('>'); /* * Don't write out any indentation whitespace now, * because there may be non-whitespace text after this. * * Simply mark that at this point if we do decide * to indent that we should * add a newline on the end of the current line before * the indentation at the start of the next line. */ m_startNewLine = true; } catch (IOException e) { throw new SAXException(e); } } if (m_tracer != null) { super.fireEscapingEvent(target, data); } } @Override public void entityReference(String name) throws org.xml.sax.SAXException { if (m_elemContext.m_startTagOpen) { closeStartTag(); m_elemContext.m_startTagOpen = false; } try { if (shouldIndent()) { indent(); } final java.io.Writer writer = m_writer; writer.write('&'); writer.write(name); writer.write(';'); } catch (IOException e) { throw new SAXException(e); } if (m_tracer != null) { super.fireEntityReference(name); } } @Override public void addUniqueAttribute(String name, String value, int flags) throws SAXException { if (m_elemContext.m_startTagOpen) { try { final String patchedName = patchName(name); final java.io.Writer writer = m_writer; if ((flags & NO_BAD_CHARS) > 0 && m_xmlcharInfo.onlyQuotAmpLtGt) { // "flags" has indicated that the characters // '>' '<' '&' and '"' are not in the value and // m_htmlcharInfo has recorded that there are no other // entities in the range 32 to 127 so we write out the // value directly writer.write(' '); writer.write(patchedName); writer.write("=\""); writer.write(value); writer.write('"'); } else { writer.write(' '); writer.write(patchedName); writer.write("=\""); writeAttrString(writer, value, this.getEncoding()); writer.write('"'); } } catch (IOException e) { throw new SAXException(e); } } } @Override public void addAttribute( String uri, String localName, String rawName, String type, String value, boolean xslAttribute) throws SAXException { if (m_elemContext.m_startTagOpen) { boolean was_added = addAttributeAlways(uri, localName, rawName, type, value, xslAttribute); /* * We don't run this block of code if: * 1. The attribute value was only replaced (was_added is false). * 2. The attribute is from an xsl:attribute element (that is handled * in the addAttributeAlways() call just above. * 3. The name starts with "xmlns", i.e. it is a namespace declaration. */ if (was_added && !xslAttribute && !rawName.startsWith("xmlns")) { String prefixUsed = ensureAttributesNamespaceIsDeclared(uri, localName, rawName); if ((prefixUsed != null) && (rawName != null) && !rawName.startsWith(prefixUsed)) { // use a different raw name, with the prefix used in the // generated namespace declaration rawName = prefixUsed + ":" + localName; } } addAttributeAlways(uri, localName, rawName, type, value, xslAttribute); } else { /* * The startTag is closed, yet we are adding an attribute? * * Section: 7.1.3 Creating Attributes Adding an attribute to an * element after a PI (for example) has been added to it is an * error. The attributes can be ignored. The spec doesn't explicitly * say this is disallowed, as it does for child elements, but it * makes sense to have the same treatment. * * We choose to ignore the attribute which is added too late. */ // Generate a warning of the ignored attributes // Create the warning message String msg = Utils.messages.createMessage( MsgKey.ER_ILLEGAL_ATTRIBUTE_POSITION, new Object[]{localName}); try { // Prepare to issue the warning message Transformer tran = super.getTransformer(); ErrorListener errHandler = tran.getErrorListener(); // Issue the warning message if (null != errHandler && m_sourceLocator != null) { errHandler.warning(new TransformerException(msg, m_sourceLocator)); } else { MLogger.inf(msg); } } catch (TransformerException e) { // A user defined error handler, errHandler, may throw // a TransformerException if it chooses to, and if it does // we will wrap it with a SAXException and re-throw. // Of course if the handler throws another type of // exception, like a RuntimeException, then that is OK too. SAXException se = new SAXException(e); throw se; } } } @Override public void endElement(String elemName) throws SAXException { endElement(null, null, elemName); } @Override public void namespaceAfterStartElement(final String prefix, final String uri) throws SAXException { // hack for XSLTC with finding URI for default namespace if (m_elemContext.m_elementURI == null) { String prefix1 = getPrefixPart(m_elemContext.m_elementName); if (prefix1 == null && EMPTYSTRING.equals(prefix)) { // the elements URI is not known yet, and it // doesn't have a prefix, and we are currently // setting the uri for prefix "", so we have // the uri for the element... lets remember it m_elemContext.m_elementURI = uri; } } startPrefixMapping(prefix, uri, false); return; } /** * From XSLTC * Declare a prefix to point to a namespace URI. Inform SAX handler * if this is a new prefix mapping. * @param prefix prefix * @param uri uri * @return boolean */ protected boolean pushNamespace(String prefix, String uri) { try { if (m_prefixMap.pushNamespace( prefix, uri, m_elemContext.m_currentElemDepth)) { startPrefixMapping(prefix, uri); return true; } } catch (SAXException e) { // falls through } return false; } @Override public boolean reset() { boolean wasReset = false; if (super.reset()) { // Make this call when resetToXMLStream does // something. // resetToXMLStream(); wasReset = true; } return wasReset; } /** * Reset all of the fields owned by ToStream class. */ private void resetToXMLStream() { // This is an empty method, but is kept for future use // as a place holder for a location to reset fields // defined within this class return; } /** * This method checks for the XML version of output document. * If XML version of output document is not specified, then output * document is of version XML 1.0. * If XML version of output doucment is specified, but it is not either * XML 1.0 or XML 1.1, a warning message is generated, the XML Version of * output document is set to XML 1.0 and processing continues. * @return string (XML version) */ private String getXMLVersion() { String xmlVersion = getVersion(); if (xmlVersion == null || xmlVersion.equals(XMLVERSION10)) { xmlVersion = XMLVERSION10; } else if (xmlVersion.equals(XMLVERSION11)) { xmlVersion = XMLVERSION11; } else { String msg = Utils.messages.createMessage( MsgKey.ER_XML_VERSION_NOT_SUPPORTED, new Object[]{xmlVersion}); try { // Prepare to issue the warning message Transformer tran = super.getTransformer(); ErrorListener errHandler = tran.getErrorListener(); // Issue the warning message if (null != errHandler && m_sourceLocator != null) { errHandler.warning(new TransformerException(msg, m_sourceLocator)); } else { MLogger.inf(msg); } } catch (Exception e) { } xmlVersion = XMLVERSION10; } return xmlVersion; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy