You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@xalan.apache.org by sa...@apache.org on 2002/06/03 19:14:22 UTC
cvs commit: xml-xalan/java/src/org/apache/xalan/xsltc/runtime/output OutputBase.java SAXHTMLOutput.java SAXOutput.java SAXXMLOutput.java StreamOutput.java StreamXMLOutput.java
santiagopg 2002/06/03 10:14:22
Modified: java/src/org/apache/xalan/xsltc/runtime/output
OutputBase.java SAXHTMLOutput.java SAXOutput.java
SAXXMLOutput.java StreamOutput.java
StreamXMLOutput.java
Log:
Moved common methods to base classes.
Revision Changes Path
1.3 +196 -24 xml-xalan/java/src/org/apache/xalan/xsltc/runtime/output/OutputBase.java
Index: OutputBase.java
===================================================================
RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/runtime/output/OutputBase.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- OutputBase.java 21 May 2002 15:13:25 -0000 1.2
+++ OutputBase.java 3 Jun 2002 17:14:22 -0000 1.3
@@ -1,5 +1,5 @@
/*
- * @(#)$Id: OutputBase.java,v 1.2 2002/05/21 15:13:25 santiagopg Exp $
+ * @(#)$Id: OutputBase.java,v 1.3 2002/06/03 17:14:22 santiagopg Exp $
*
* The Apache Software License, Version 1.1
*
@@ -63,35 +63,207 @@
package org.apache.xalan.xsltc.runtime.output;
+import java.util.Stack;
+
+import org.apache.xalan.xsltc.*;
+import org.apache.xalan.xsltc.runtime.*;
+import org.apache.xalan.xsltc.runtime.Hashtable;
+
import org.apache.xalan.xsltc.TransletException;
import org.apache.xalan.xsltc.TransletOutputHandler;
import org.apache.xalan.xsltc.runtime.Hashtable;
-public abstract class OutputBase implements TransletOutputHandler {
+public abstract class OutputBase implements TransletOutputHandler, Constants {
+
+ /**
+ * Document system identifier
+ */
+ protected String _doctypeSystem = null;
+
+ /**
+ * Document public identifier
+ */
+ protected String _doctypePublic = null;
+
+ /**
+ * Holds the current tree depth.
+ */
+ protected int _depth = 0;
+
+ /**
+ * Each entry (prefix) in this hashtable points to a Stack of URIs
+ */
+ protected Hashtable _namespaces;
+
+ /**
+ * The top of this stack contains an id of the element that last declared
+ * a namespace. Used to ensure prefix/uri map scopes are closed correctly
+ */
+ protected Stack _nodeStack;
+
+ /**
+ * The top of this stack is the prefix that was last mapped to an URI
+ */
+ protected Stack _prefixStack;
+
+ /**
+ * Contains all elements that should be output as CDATA sections.
+ */
+ protected Hashtable _cdata = null;
+
+ /**
+ * The top of this stack contains the element id of the last element whose
+ * contents should be output as CDATA sections.
+ */
+ protected Stack _cdataStack;
+
+ /**
+ * Set to true when a CDATA section is being output.
+ */
+ protected boolean _cdataTagOpen = false;
+
+ /**
+ * Set to true when a start tag is being output.
+ */
+ protected boolean _startTagOpen = false;
+
+ /**
+ * Initialize global variables
+ */
+ protected void initCDATA() {
+ // CDATA stack
+ _cdataStack = new Stack();
+ _cdataStack.push(new Integer(-1)); // push dummy value
+ }
+
+ protected void initNamespaces() {
+ // Namespaces
+ _namespaces = new Hashtable();
+ _nodeStack = new Stack();
+ _prefixStack = new Stack();
+
+ // Define the default namespace (initially maps to "" uri)
+ Stack stack;
+ _namespaces.put(EMPTYSTRING, stack = new Stack());
+ stack.push(EMPTYSTRING);
+ _prefixStack.push(EMPTYSTRING);
+
+ _namespaces.put(XML_PREFIX, stack = new Stack());
+ stack.push("http://www.w3.org/XML/1998/namespace");
+ _prefixStack.push(XML_PREFIX);
+
+ _nodeStack.push(new Integer(-1));
+ _depth = 0;
+ }
+
+ /**
+ * Set the output document system/public identifiers
+ */
+ public void setDoctype(String system, String pub) {
+ _doctypeSystem = system;
+ _doctypePublic = pub;
+
+ }
+
+ public void setCdataElements(Hashtable elements) {
+ _cdata = elements;
+ }
+
+
+ /**
+ * TODO: This method is a HACK! Since XSLTC does not have access to the
+ * XML file, it sometimes generates a NS prefix of the form "ns?" for
+ * an attribute. If at runtime, when the qname of the attribute is
+ * known, another prefix is specified for the attribute, then we can get
+ * a qname of the form "ns?:otherprefix:name". This function patches the
+ * qname by simply ignoring "otherprefix".
+ */
+ protected static String patchName(String qname) throws TransletException {
+ final int lastColon = qname.lastIndexOf(':');
+ if (lastColon > 0) {
+ final int firstColon = qname.indexOf(':');
+ if (firstColon != lastColon) {
+ return qname.substring(0, firstColon) +
+ qname.substring(lastColon);
+ }
+ }
+ return qname;
+ }
+
+ /**
+ * Declare a prefix to point to a namespace URI
+ */
+ protected boolean pushNamespace(String prefix, String uri) {
+ // Prefixes "xml" and "xmlns" cannot be redefined
+ if (prefix.startsWith(XML_PREFIX)) {
+ return false;
+ }
+
+ Stack stack;
+ // Get the stack that contains URIs for the specified prefix
+ if ((stack = (Stack)_namespaces.get(prefix)) == null) {
+ _namespaces.put(prefix, stack = new Stack());
+ }
- public void startDocument() throws TransletException{}
- public void endDocument() throws TransletException{}
- public void startElement(String elementName) throws TransletException{}
- public void endElement(String elementName) throws TransletException{}
- public void characters(String characters) throws TransletException{}
+ if (!stack.empty() && uri.equals(stack.peek())) {
+ return false;
+ }
+
+ stack.push(uri);
+ _prefixStack.push(prefix);
+ _nodeStack.push(new Integer(_depth));
+ return true;
+ }
+
+ /**
+ * Undeclare the namespace that is currently pointed to by a given prefix
+ */
+ protected void popNamespace(String prefix) {
+ // Prefixes "xml" and "xmlns" cannot be redefined
+ if (prefix.startsWith(XML_PREFIX)) {
+ return;
+ }
+
+ Stack stack;
+ if ((stack = (Stack)_namespaces.get(prefix)) != null) {
+ stack.pop();
+ }
+ }
+
+ /**
+ * Pop all namespace definitions that were delcared by the current element
+ */
+ protected void popNamespaces() {
+ while (true) {
+ if (_nodeStack.isEmpty()) return;
+ Integer i = (Integer)(_nodeStack.peek());
+ if (i.intValue() != _depth) return;
+ _nodeStack.pop();
+ popNamespace((String)_prefixStack.pop());
+ }
+ }
+
+ // -- Temporary
+ public void startDocument() throws TransletException { }
+ public void endDocument() throws TransletException { }
+ public void startElement(String elementName) throws TransletException { }
+ public void endElement(String elementName) throws TransletException { }
+ public void characters(String characters) throws TransletException { }
public void characters(char[] characters, int offset, int length)
- throws TransletException{}
+ throws TransletException { }
public void attribute(String attributeName, String attributeValue)
- throws TransletException{}
- public void namespace(String prefix, String uri) throws TransletException{}
- public void comment(String comment) throws TransletException{}
+ throws TransletException { }
+ public void namespace(String prefix, String uri) throws TransletException { }
+ public void comment(String comment) throws TransletException { }
public void processingInstruction(String target, String data)
- throws TransletException{}
- public void setType(int type){}
- public void setIndent(boolean indent){}
- public void omitHeader(boolean value){}
- public boolean setEscaping(boolean escape) throws TransletException{
- return false;
- }
- public void setCdataElements(Hashtable elements){}
- public void setDoctype(String system, String pub) {}
- public void setMediaType(String mediaType) {}
- public void setStandalone(String standalone) {}
- public void setVersion(String version) {}
- public void close() {}
+ throws TransletException { }
+ public void setType(int type) { }
+ public void setIndent(boolean indent) { }
+ public void omitHeader(boolean value) { }
+ public boolean setEscaping(boolean escape) throws TransletException { return true; }
+ public void setMediaType(String mediaType) { }
+ public void setStandalone(String standalone) { }
+ public void setVersion(String version) { }
+ public void close() { }
+
}
1.5 +17 -43 xml-xalan/java/src/org/apache/xalan/xsltc/runtime/output/SAXHTMLOutput.java
Index: SAXHTMLOutput.java
===================================================================
RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/runtime/output/SAXHTMLOutput.java,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- SAXHTMLOutput.java 21 May 2002 18:55:10 -0000 1.4
+++ SAXHTMLOutput.java 3 Jun 2002 17:14:22 -0000 1.5
@@ -1,5 +1,5 @@
/*
- * @(#)$Id: SAXHTMLOutput.java,v 1.4 2002/05/21 18:55:10 tmiller Exp $
+ * @(#)$Id: SAXHTMLOutput.java,v 1.5 2002/06/03 17:14:22 santiagopg Exp $
*
* The Apache Software License, Version 1.1
*
@@ -63,48 +63,43 @@
package org.apache.xalan.xsltc.runtime.output;
+import java.util.Stack;
+import java.io.IOException;
+
import org.xml.sax.SAXException;
import org.xml.sax.ContentHandler;
import org.xml.sax.ext.LexicalHandler;
import org.apache.xalan.xsltc.TransletException;
import org.apache.xalan.xsltc.runtime.BasisLibrary;
import org.apache.xalan.xsltc.runtime.AttributeList;
-import java.io.IOException;
-import java.util.Stack;
-public class SAXHTMLOutput extends SAXOutput {
- private boolean _headTagOpen = false;
- private String _mediaType = "text/html";
+public class SAXHTMLOutput extends SAXOutput {
+ private boolean _headTagOpen = false;
+ private String _mediaType = "text/html";
- public SAXHTMLOutput(ContentHandler handler, String encoding) throws
- IOException
+ public SAXHTMLOutput(ContentHandler handler, String encoding)
+ throws IOException
{
super(handler, encoding);
- init();
}
public SAXHTMLOutput(ContentHandler handler, LexicalHandler lex,
String encoding) throws IOException
{
super(handler, lex, encoding);
- init();
}
- private void init() throws IOException {
- _qnameStack = new Stack();
- }
-
-
public void attribute(String name, final String value)
throws TransletException
{
- final String patchedName = patchQName(name);
+ final String patchedName = patchName(name);
final String localName = getLocalName(patchedName);
final int index = _attributes.getIndex(name);
if (!_startTagOpen) {
BasisLibrary.runTimeError(BasisLibrary.STRAY_ATTRIBUTE_ERR,name);
}
+
if (index >= 0) {
_attributes.setAttribute(index, EMPTYSTRING, EMPTYSTRING,
name, "CDATA", value);
@@ -187,7 +182,6 @@
_elementName = elementName;
_attributes.clear();
_startTagOpen = true;
- _qnameStack.push(elementName);
// Insert <META> tag directly after <HEAD> element in HTML doc
if (elementName.toLowerCase().equals("head")) {
@@ -198,19 +192,18 @@
}
}
-
-
-
/**
* End an element or CDATA section in the output document
*/
public void endElement(String elementName) throws TransletException {
try {
// Close any open element
- if (_startTagOpen) closeStartTag();
- _saxHandler.endElement(EMPTYSTRING, EMPTYSTRING,
- (String)(_qnameStack.pop()));
- } catch (SAXException e) {
+ if (_startTagOpen) {
+ closeStartTag();
+ }
+ _saxHandler.endElement(EMPTYSTRING, EMPTYSTRING, elementName);
+ }
+ catch (SAXException e) {
throw new TransletException(e);
}
@@ -241,23 +234,4 @@
throw new TransletException(e);
}
}
-
-
- private void initNamespaces() {
- //empty
- }
-
- private String lookupNamespace(String prefix) {
- return null; // no-op
- }
-
- private void popNamespace(String prefix) throws SAXException {
- //empty
- }
-
- private String getNamespaceURI(String qname, boolean isElement)
- throws TransletException
- {
- return null; // no-op
- }
}
1.6 +9 -45 xml-xalan/java/src/org/apache/xalan/xsltc/runtime/output/SAXOutput.java
Index: SAXOutput.java
===================================================================
RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/runtime/output/SAXOutput.java,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- SAXOutput.java 21 May 2002 18:55:10 -0000 1.5
+++ SAXOutput.java 3 Jun 2002 17:14:22 -0000 1.6
@@ -1,5 +1,5 @@
/*
- * @(#)$Id: SAXOutput.java,v 1.5 2002/05/21 18:55:10 tmiller Exp $
+ * @(#)$Id: SAXOutput.java,v 1.6 2002/06/03 17:14:22 santiagopg Exp $
*
* The Apache Software License, Version 1.1
*
@@ -72,23 +72,15 @@
import org.apache.xalan.xsltc.runtime.Constants;
public class SAXOutput extends OutputBase implements Constants {
+
protected ContentHandler _saxHandler;
protected LexicalHandler _lexHandler;
- protected boolean _startTagOpen = false;
protected AttributesImpl _attributes = new AttributesImpl();
+
protected String _elementName = null;
- // parameters set by <xsl:output> element, or by set/getOutputProperty()
protected String _encoding = null;
- protected String _doctypeSystem = null;
- protected String _doctypePublic = null;
- // The top of this stack contains the QName of the currently open element
- protected Stack _qnameStack;
-
- // Holds the current tree depth (see startElement() and endElement()).
- protected int _depth = 0;
-
public SAXOutput(ContentHandler handler, String encoding) {
_saxHandler = handler;
@@ -101,11 +93,11 @@
_encoding = encoding;
}
-
public void startDocument() throws TransletException {
try {
_saxHandler.startDocument();
- } catch (SAXException e) {
+ }
+ catch (SAXException e) {
throw new TransletException(e);
}
}
@@ -113,7 +105,8 @@
public void endDocument() throws TransletException {
try {
_saxHandler.endDocument();
- } catch (SAXException e) {
+ }
+ catch (SAXException e) {
throw new TransletException(e);
}
}
@@ -125,39 +118,10 @@
try {
_saxHandler.characters(characters.toCharArray(), 0,
characters.length());
- } catch (SAXException e) {
+ }
+ catch (SAXException e) {
throw new TransletException(e);
}
- }
-
- /**
- * Set the output document system/public identifiers
- */
- public void setDoctype(String system, String pub) {
- _doctypeSystem = system;
- _doctypePublic = pub;
- }
-
-
-
- /**
- * TODO: This method is a HACK! Since XSLTC does not have access to the
- * XML file, it sometimes generates a NS prefix of the form "ns?" for
- * an attribute. If at runtime, when the qname of the attribute is
- * known, another prefix is specified for the attribute, then we can get
- * a qname of the form "ns?:otherprefix:name". This function patches the
- * qname by simply ignoring "otherprefix".
- */
- protected static String patchQName(String qname) throws TransletException {
- final int lastColon = qname.lastIndexOf(':');
- if (lastColon > 0) {
- final int firstColon = qname.indexOf(':');
- if (firstColon != lastColon) {
- return qname.substring(0, firstColon) +
- qname.substring(lastColon);
- }
- }
- return qname;
}
/**
1.6 +133 -254 xml-xalan/java/src/org/apache/xalan/xsltc/runtime/output/SAXXMLOutput.java
Index: SAXXMLOutput.java
===================================================================
RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/runtime/output/SAXXMLOutput.java,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- SAXXMLOutput.java 29 May 2002 13:04:38 -0000 1.5
+++ SAXXMLOutput.java 3 Jun 2002 17:14:22 -0000 1.6
@@ -1,5 +1,5 @@
/*
- * @(#)$Id: SAXXMLOutput.java,v 1.5 2002/05/29 13:04:38 tmiller Exp $
+ * @(#)$Id: SAXXMLOutput.java,v 1.6 2002/06/03 17:14:22 santiagopg Exp $
*
* The Apache Software License, Version 1.1
*
@@ -72,121 +72,81 @@
import org.xml.sax.SAXException;
import org.apache.xalan.xsltc.runtime.BasisLibrary;
-public class SAXXMLOutput extends SAXOutput {
-
- // Each entry (prefix) in this hashtable points to a Stack of URIs
- private Hashtable _namespaces;
- // The top of this stack contains an id of the element that last declared
- // a namespace. Used to ensure prefix/uri map scopes are closed correctly
- private Stack _nodeStack;
- // The top of this stack is the prefix that was last mapped to an URI
- private Stack _prefixStack;
-
-
- // Contains all elements that should be output as CDATA sections
- private Hashtable _cdata = null;
-
- private boolean _cdataTagOpen = false;
- // The top of this stack contains the element id of the last element whose
- // contents should be output as CDATA sections.
- private Stack _cdataStack;
-
- // The top of this stack contains the QName of the currently open element
- private Stack _qnameStack;
+public class SAXXMLOutput extends SAXOutput {
private static final char[] BEGCDATA = "<![CDATA[".toCharArray();
private static final char[] ENDCDATA = "]]>".toCharArray();
private static final char[] CNTCDATA = "]]]]><![CDATA[>".toCharArray();
-
public SAXXMLOutput(ContentHandler handler, String encoding)
throws IOException
{
super(handler, encoding);
- init();
+ initCDATA();
+ initNamespaces();
}
public SAXXMLOutput(ContentHandler handler, LexicalHandler lex,
String encoding) throws IOException
{
super(handler, lex, encoding);
- init();
- }
-
- private void init() throws IOException {
- _cdataTagOpen = false;
- _cdataStack = new Stack();
- _cdataStack.push(new Integer(-1)); // push dummy value
- _qnameStack = new Stack();
-
- // Reset our internal namespace handling
- initNamespaces();
+ initCDATA();
+ initNamespaces();
}
public void endDocument() throws TransletException {
try {
// Close any open start tag
- if (_startTagOpen) closeStartTag();
- if (_cdataTagOpen) closeCDATA();
+ if (_startTagOpen) {
+ closeStartTag();
+ }
+ else if (_cdataTagOpen) {
+ closeCDATA();
+ }
// Close output document
_saxHandler.endDocument();
- } catch (SAXException e) {
+ }
+ catch (SAXException e) {
throw new TransletException(e);
}
}
/**
- * This method is called when all the data needed for a call to the
- * SAX handler's startElement() method has been gathered.
- */
- public void closeStartTag() throws TransletException {
- try {
- _startTagOpen = false;
-
- // Now is time to send the startElement event
- _saxHandler.startElement(getNamespaceURI(_elementName, true),
- getLocalName(_elementName), _elementName, _attributes);
- }
- catch (SAXException e) {
- throw new TransletException(e);
- }
- }
-
- /**
- * Returns the URI of an element or attribute. Note that default namespaces
- * do not apply directly to attributes.
+ * Start an element in the output document. This might be an XML
+ * element (<elem>data</elem> type) or a CDATA section.
*/
- private String getNamespaceURI(String qname, boolean isElement)
- throws TransletException
- {
- String uri = EMPTYSTRING;
- int col = qname.lastIndexOf(':');
- final String prefix = (col > 0) ? qname.substring(0, col) : EMPTYSTRING;
+ public void startElement(String elementName) throws TransletException {
+ try {
+ // Close any open start tag
+ if (_startTagOpen) {
+ closeStartTag();
+ }
+ else if (_cdataTagOpen) {
+ closeCDATA();
+ }
- if (prefix != EMPTYSTRING || isElement) {
- uri = lookupNamespace(prefix);
- if (uri == null && !prefix.equals(XMLNS_PREFIX)) {
- BasisLibrary.runTimeError(BasisLibrary.NAMESPACE_PREFIX_ERR,
- qname.substring(0, col));
+ // Handle document type declaration (for first element only)
+ if (_lexHandler != null) {
+ if (_doctypeSystem != null) {
+ _lexHandler.startDTD(elementName, _doctypePublic,
+ _doctypeSystem);
+ }
+ _lexHandler = null;
}
- }
- return uri;
- }
- /**
- * Use a namespace prefix to lookup a namespace URI
- */
- private String lookupNamespace(String prefix) {
- final Stack stack = (Stack)_namespaces.get(prefix);
- return stack != null && !stack.isEmpty() ? (String)stack.peek() : null;
- }
+ _depth++;
+ _elementName = elementName;
+ _attributes.clear();
+ _startTagOpen = true;
-
- private void closeCDATA() throws SAXException {
- // Output closing bracket - "]]>"
- _saxHandler.characters(ENDCDATA, 0, ENDCDATA.length);
- _cdataTagOpen = false;
+ if (_cdata != null && _cdata.get(elementName) != null) {
+ _cdataStack.push(new Integer(_depth));
+ }
+ }
+ catch (SAXException e) {
+ throw new TransletException(e);
+ }
}
/**
@@ -196,31 +156,26 @@
public void attribute(String name, final String value)
throws TransletException
{
- final String patchedName = patchQName(name);
+ final String patchedName = patchName(name);
final String localName = getLocalName(patchedName);
final String uri = getNamespaceURI(patchedName, false);
+
final int index = (localName == null) ?
_attributes.getIndex(name) : /* don't use patchedName */
_attributes.getIndex(uri, localName);
+
if (!_startTagOpen) {
BasisLibrary.runTimeError(BasisLibrary.STRAY_ATTRIBUTE_ERR,
patchedName);
}
- // Output as namespace declaration
- if (name.startsWith(XMLNS_PREFIX)) {
- namespace(name.length() > 6 ? name.substring(6) : EMPTYSTRING,
- value);
- }
- else {
- if (index >= 0) { // Duplicate attribute?
- _attributes.setAttribute(index, uri, localName,
- patchedName, "CDATA", value);
- }
- else {
- _attributes.addAttribute(uri, localName, patchedName,
- "CDATA", value);
- }
+ if (index >= 0) { // Duplicate attribute?
+ _attributes.setAttribute(index, uri, localName,
+ patchedName, "CDATA", value);
+ }
+ else {
+ _attributes.addAttribute(uri, localName, patchedName,
+ "CDATA", value);
}
}
@@ -229,13 +184,10 @@
{
try {
// Close any open start tag
- if (_startTagOpen) closeStartTag();
+ if (_startTagOpen) {
+ closeStartTag();
+ }
- // Take special precautions if within a CDATA section. If we
- // encounter the sequence ']]>' within the CDATA, we need to
- // break the section in two and leave the ']]' at the end of
- // the first CDATA and '>' at the beginning of the next. Other
- // special characters/sequences are _NOT_ escaped within CDATA.
Integer I = (Integer)_cdataStack.peek();
if ((I.intValue() == _depth) && (!_cdataTagOpen)) {
startCDATA(ch, off, len);
@@ -252,12 +204,15 @@
public void endElement(String elementName) throws TransletException {
try {
// Close any open element
- if (_startTagOpen) closeStartTag();
- if (_cdataTagOpen) closeCDATA();
+ if (_startTagOpen) {
+ closeStartTag();
+ }
+ else if (_cdataTagOpen) {
+ closeCDATA();
+ }
- final String qname = (String) _qnameStack.pop();
- _saxHandler.endElement(getNamespaceURI(qname, true),
- getLocalName(qname), qname);
+ _saxHandler.endElement(getNamespaceURI(elementName, true),
+ getLocalName(elementName), elementName);
popNamespaces();
if (((Integer)_cdataStack.peek()).intValue() == _depth){
@@ -265,140 +220,103 @@
}
_depth--;
- } catch (SAXException e) {
+ }
+ catch (SAXException e) {
throw new TransletException(e);
}
}
/**
- * The <xsl:output method="xml"/> instruction can specify that certain
- * XML elements should be output as CDATA sections. This methods allows
- * the translet to insert these elements into a hashtable of strings.
- * Every output element is looked up in this hashtable before it is
- * output.
+ * Send a namespace declaration in the output document. The namespace
+ * declaration will not be include if the namespace is already in scope
+ * with the same prefix.
*/
- public void setCdataElements(Hashtable elements) {
- _cdata = elements;
+ public void namespace(final String prefix, final String uri)
+ throws TransletException
+ {
+ if (_startTagOpen) {
+ pushNamespace(prefix, uri);
+ }
+ else {
+ if ((prefix == EMPTYSTRING) && (uri == EMPTYSTRING)) return;
+ BasisLibrary.runTimeError(BasisLibrary.STRAY_NAMESPACE_ERR,
+ prefix, uri);
+ }
}
-
/**
- * Start an element in the output document. This might be an XML
- * element (<elem>data</elem> type) or a CDATA section.
+ * This method is called when all the data needed for a call to the
+ * SAX handler's startElement() method has been gathered.
*/
- public void startElement(String elementName) throws TransletException {
- try {
- // Close any open start tag
- if (_startTagOpen) closeStartTag();
- if (_cdataTagOpen) closeCDATA();
-
- // Handle document type declaration (for first element only)
- if (_lexHandler != null) {
- if (_doctypeSystem != null) {
- _lexHandler.startDTD(elementName,
- _doctypePublic,_doctypeSystem);
- }
- _lexHandler = null;
- }
-
- _depth++;
- _elementName = elementName;
- _attributes.clear();
- _startTagOpen = true;
- _qnameStack.push(elementName);
+ private void closeStartTag() throws TransletException {
+ try {
+ _startTagOpen = false;
- if ((_cdata != null) && (_cdata.get(elementName) != null)) {
- _cdataStack.push(new Integer(_depth));
- }
- }
+ // Now is time to send the startElement event
+ _saxHandler.startElement(getNamespaceURI(_elementName, true),
+ getLocalName(_elementName), _elementName, _attributes);
+ }
catch (SAXException e) {
throw new TransletException(e);
}
}
/**
- * Initialize namespace stacks
- */
- private void initNamespaces() {
- _namespaces = new Hashtable();
- _nodeStack = new Stack();
- _prefixStack = new Stack();
-
- // Define the default namespace (initially maps to "" uri)
- Stack stack;
- _namespaces.put(EMPTYSTRING, stack = new Stack());
- stack.push(EMPTYSTRING);
- _prefixStack.push(EMPTYSTRING);
-
- _namespaces.put(XML_PREFIX, stack = new Stack());
- stack.push("http://www.w3.org/XML/1998/namespace");
- _prefixStack.push(XML_PREFIX);
-
- _nodeStack.push(new Integer(-1));
- _depth = 0;
- }
-
- /**
- * Pop all namespace definitions that were delcared by the current element
+ * Send a processing instruction to the output document
*/
- private void popNamespaces() throws TransletException {
+ public void processingInstruction(String target, String data)
+ throws TransletException {
try {
- while (true) {
- if (_nodeStack.isEmpty()) return;
- Integer i = (Integer)(_nodeStack.peek());
- if (i.intValue() != _depth) return;
- _nodeStack.pop();
- popNamespace((String)_prefixStack.pop());
- }
+ // Close any open element
+ if (_startTagOpen) {
+ closeStartTag();
+ }
+ else if (_cdataTagOpen) {
+ closeCDATA();
+ }
+
+ // Pass the processing instruction to the SAX handler
+ _saxHandler.processingInstruction(target, data);
}
catch (SAXException e) {
throw new TransletException(e);
}
}
-
/**
- * Undeclare the namespace that is currently pointed to by a given prefix
+ * Returns the URI of an element or attribute. Note that default namespaces
+ * do not apply directly to attributes.
*/
- private void popNamespace(String prefix) throws SAXException {
- // Prefixes "xml" and "xmlns" cannot be redefined
- if (prefix.equals(XML_PREFIX)) return;
-
- Stack stack;
- if ((stack = (Stack)_namespaces.get(prefix)) != null) {
- stack.pop();
- _saxHandler.endPrefixMapping(prefix);
+ private String getNamespaceURI(String qname, boolean isElement)
+ throws TransletException
+ {
+ String uri = EMPTYSTRING;
+ int col = qname.lastIndexOf(':');
+ final String prefix = (col > 0) ? qname.substring(0, col) : EMPTYSTRING;
+
+ if (prefix != EMPTYSTRING || isElement) {
+ uri = lookupNamespace(prefix);
+ if (uri == null && !prefix.equals(XMLNS_PREFIX)) {
+ BasisLibrary.runTimeError(BasisLibrary.NAMESPACE_PREFIX_ERR,
+ qname.substring(0, col));
+ }
}
+ return uri;
}
-
/**
- * Declare a prefix to point to a namespace URI
+ * Use a namespace prefix to lookup a namespace URI
*/
- private void pushNamespace(String prefix, String uri) throws SAXException {
- // Prefixes "xml" and "xmlns" cannot be redefined
- if (prefix.equals(XML_PREFIX)) return;
-
- Stack stack;
- // Get the stack that contains URIs for the specified prefix
- if ((stack = (Stack)_namespaces.get(prefix)) == null) {
- stack = new Stack();
- _namespaces.put(prefix, stack);
- }
- // Quit now if the URI the prefix currently maps to is the same as this
- if (!stack.empty() && uri.equals(stack.peek())) return;
- // Put this URI on top of the stack for this prefix
- stack.push(uri);
-
- _prefixStack.push(prefix);
- _nodeStack.push(new Integer(_depth));
-
- // Inform the SAX handler
- _saxHandler.startPrefixMapping(prefix, uri);
+ private String lookupNamespace(String prefix) {
+ final Stack stack = (Stack)_namespaces.get(prefix);
+ return stack != null && !stack.isEmpty() ? (String)stack.peek() : null;
}
-
-
+ private void closeCDATA() throws SAXException {
+ // Output closing bracket - "]]>"
+ _saxHandler.characters(ENDCDATA, 0, ENDCDATA.length);
+ _cdataTagOpen = false;
+ }
/**
* Utility method - pass a whole charactes as CDATA to SAX handler
@@ -411,59 +329,20 @@
_saxHandler.characters(BEGCDATA, 0, BEGCDATA.length);
// Detect any occurence of "]]>" in the character array
- for (int i = offset; i < limit-2; i++) {
- if (ch[i] == ']' && ch[i+1] == ']' && ch[i+2] == '>') {
+ for (int i = offset; i < limit - 2; i++) {
+ if (ch[i] == ']' && ch[i + 1] == ']' && ch[i + 2] == '>') {
_saxHandler.characters(ch, offset, i - offset);
_saxHandler.characters(CNTCDATA, 0, CNTCDATA.length);
offset = i+3;
- i=i+2; // Skip next chars ']' and '>'.
+ i += 2; // Skip next chars ']' and '>'
}
}
// Output the remaining characters
- if (offset < limit) _saxHandler.characters(ch, offset, limit - offset);
-
+ if (offset < limit) {
+ _saxHandler.characters(ch, offset, limit - offset);
+ }
_cdataTagOpen = true;
- }
-
- /**
- * Send a namespace declaration in the output document. The namespace
- * declaration will not be include if the namespace is already in scope
- * with the same prefix.
- */
- public void namespace(final String prefix, final String uri)
- throws TransletException {
- try {
- if (_startTagOpen)
- pushNamespace(prefix, uri);
- else {
- if ((prefix == EMPTYSTRING) && (uri == EMPTYSTRING)) return;
- BasisLibrary.runTimeError(BasisLibrary.STRAY_NAMESPACE_ERR,
- prefix, uri);
- }
- }
- catch (SAXException e) {
- throw new TransletException(e);
- }
- }
-
-
- /**
- * Send a processing instruction to the output document
- */
- public void processingInstruction(String target, String data)
- throws TransletException {
- try {
- // Close any open element
- if (_startTagOpen) closeStartTag();
- if (_cdataTagOpen) closeCDATA();
-
- // Pass the processing instruction to the SAX handler
- _saxHandler.processingInstruction(target, data);
- }
- catch (SAXException e) {
- throw new TransletException(e);
- }
}
}
1.9 +1 -6 xml-xalan/java/src/org/apache/xalan/xsltc/runtime/output/StreamOutput.java
Index: StreamOutput.java
===================================================================
RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/runtime/output/StreamOutput.java,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- StreamOutput.java 29 May 2002 20:25:15 -0000 1.8
+++ StreamOutput.java 3 Jun 2002 17:14:22 -0000 1.9
@@ -1,5 +1,5 @@
/*
- * @(#)$Id: StreamOutput.java,v 1.8 2002/05/29 20:25:15 santiagopg Exp $
+ * @(#)$Id: StreamOutput.java,v 1.9 2002/06/03 17:14:22 santiagopg Exp $
*
* The Apache Software License, Version 1.1
*
@@ -92,9 +92,7 @@
protected Writer _writer;
protected StringBuffer _buffer;
- protected boolean _startTagOpen = false;
protected boolean _is8859Encoded = false;
-
protected boolean _indent = false;
protected boolean _omitHeader = false;
protected String _standalone = null;
@@ -108,9 +106,6 @@
protected boolean _escaping = true;
protected boolean _firstElement = true;
protected String _encoding = "UTF-8";
-
- protected String _doctypeSystem = null;
- protected String _doctypePublic = null;
// protected HashSet _attributes = new HashSet();
protected Vector _attributes = new Vector();
1.9 +7 -143 xml-xalan/java/src/org/apache/xalan/xsltc/runtime/output/StreamXMLOutput.java
Index: StreamXMLOutput.java
===================================================================
RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/runtime/output/StreamXMLOutput.java,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- StreamXMLOutput.java 31 May 2002 18:22:14 -0000 1.8
+++ StreamXMLOutput.java 3 Jun 2002 17:14:22 -0000 1.9
@@ -1,5 +1,5 @@
/*
- * @(#)$Id: StreamXMLOutput.java,v 1.8 2002/05/31 18:22:14 santiagopg Exp $
+ * @(#)$Id: StreamXMLOutput.java,v 1.9 2002/06/03 17:14:22 santiagopg Exp $
*
* The Apache Software License, Version 1.1
*
@@ -76,7 +76,7 @@
import org.apache.xalan.xsltc.runtime.*;
import org.apache.xalan.xsltc.runtime.Hashtable;
-public class StreamXMLOutput extends StreamOutput implements Constants {
+public class StreamXMLOutput extends StreamOutput {
private static final String BEGCDATA = "<![CDATA[";
private static final String ENDCDATA = "]]>";
@@ -86,77 +86,18 @@
private static final String CDATA_ESC_START = "]]>&#";
private static final String CDATA_ESC_END = ";<![CDATA[";
- /**
- * Holds the current tree depth.
- */
- private int _depth = 0;
-
- /**
- * Each entry (prefix) in this hashtable points to a Stack of URIs
- */
- private Hashtable _namespaces;
-
- /**
- * The top of this stack contains an id of the element that last declared
- * a namespace. Used to ensure prefix/uri map scopes are closed correctly
- */
- private Stack _nodeStack;
-
- /**
- * The top of this stack is the prefix that was last mapped to an URI
- */
- private Stack _prefixStack;
-
- /**
- * Contains all elements that should be output as CDATA sections.
- */
- private Hashtable _cdata = null;
-
- /**
- * The top of this stack contains the element id of the last element whose
- * contents should be output as CDATA sections.
- */
- private Stack _cdataStack;
-
- private boolean _cdataTagOpen = false;
-
public StreamXMLOutput(Writer writer, String encoding) {
super(writer, encoding);
- init();
+ initCDATA();
+ initNamespaces();
}
public StreamXMLOutput(OutputStream out, String encoding)
throws IOException
{
super(out, encoding);
- init();
- }
-
- /**
- * Initialize global variables
- */
- private void init() {
- // CDATA stack
- _cdataStack = new Stack();
- _cdataStack.push(new Integer(-1)); // push dummy value
-
- // Namespaces
- _namespaces = new Hashtable();
- _nodeStack = new Stack();
- _prefixStack = new Stack();
-
- // Define the default namespace (initially maps to "" uri)
- Stack stack;
- _namespaces.put(EMPTYSTRING, stack = new Stack());
- stack.push(EMPTYSTRING);
- _prefixStack.push(EMPTYSTRING);
-
- _namespaces.put(XML_PREFIX, stack = new Stack());
- stack.push("http://www.w3.org/XML/1998/namespace");
- _prefixStack.push(XML_PREFIX);
-
- _nodeStack.push(new Integer(-1));
- _depth = 0;
+ initCDATA();
+ initNamespaces();
}
public void startDocument() throws TransletException {
@@ -335,11 +276,7 @@
return temp;
}
- public void setCdataElements(Hashtable elements) {
- _cdata = elements;
- }
-
- public void namespace(final String prefix, final String uri)
+ public void namespace(final String prefix, final String uri)
throws TransletException
{
// System.out.println("namespace prefix = " + prefix + " uri = " + uri);
@@ -360,59 +297,6 @@
}
/**
- * Declare a prefix to point to a namespace URI
- */
- private boolean pushNamespace(String prefix, String uri) {
- // Prefixes "xml" and "xmlns" cannot be redefined
- if (prefix.startsWith(XML_PREFIX)) {
- return false;
- }
-
- Stack stack;
- // Get the stack that contains URIs for the specified prefix
- if ((stack = (Stack)_namespaces.get(prefix)) == null) {
- _namespaces.put(prefix, stack = new Stack());
- }
-
- if (!stack.empty() && uri.equals(stack.peek())) {
- return false;
- }
-
- stack.push(uri);
- _prefixStack.push(prefix);
- _nodeStack.push(new Integer(_depth));
- return true;
- }
-
- /**
- * Undeclare the namespace that is currently pointed to by a given prefix
- */
- private void popNamespace(String prefix) {
- // Prefixes "xml" and "xmlns" cannot be redefined
- if (prefix.startsWith(XML_PREFIX)) {
- return;
- }
-
- Stack stack;
- if ((stack = (Stack)_namespaces.get(prefix)) != null) {
- stack.pop();
- }
- }
-
- /**
- * Pop all namespace definitions that were delcared by the current element
- */
- private void popNamespaces() {
- while (true) {
- if (_nodeStack.isEmpty()) return;
- Integer i = (Integer)(_nodeStack.peek());
- if (i.intValue() != _depth) return;
- _nodeStack.pop();
- popNamespace((String)_prefixStack.pop());
- }
- }
-
- /**
* Utility method - pass a whole charactes as CDATA to SAX handler
*/
private void startCDATA(char[] ch, int off, int len) {
@@ -511,25 +395,5 @@
result.append(ch, offset, limit - offset);
}
return result.toString();
- }
-
- /**
- * TODO: This method is a HACK! Since XSLTC does not have access to the
- * XML file, it sometimes generates a NS prefix of the form "ns?" for
- * an attribute. If at runtime, when the qname of the attribute is
- * known, another prefix is specified for the attribute, then we can get
- * a qname of the form "ns?:otherprefix:name". This function patches the
- * name by simply ignoring "otherprefix".
- */
- private static String patchName(String qname) {
- final int lastColon = qname.lastIndexOf(':');
- if (lastColon > 0) {
- final int firstColon = qname.indexOf(':');
- if (firstColon != lastColon) {
- return qname.substring(0, firstColon) +
- qname.substring(lastColon);
- }
- }
- return qname;
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: xalan-cvs-unsubscribe@xml.apache.org
For additional commands, e-mail: xalan-cvs-help@xml.apache.org