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

net.sf.saxon.pull.PullToStax Maven / Gradle / Ivy

Go to download

Provides a basic XSLT 2.0 and XQuery 1.0 processor (W3C Recommendations, January 2007). Command line interfaces and implementations of several Java APIs (DOM, XPath, s9api) are also included.

The newest version!
package net.sf.saxon.pull;

import net.sf.saxon.om.AttributeCollection;
import net.sf.saxon.om.FastStringBuffer;
import net.sf.saxon.om.NamePool;
import net.sf.saxon.trans.XPathException;
import net.sf.saxon.value.Whitespace;
import net.sf.saxon.pull.NamespaceContextImpl;
import net.sf.saxon.expr.ExpressionLocation;

import javax.xml.namespace.NamespaceContext;
import javax.xml.namespace.QName;
import javax.xml.stream.Location;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import javax.xml.transform.SourceLocator;

/**
 * This class bridges PullProvider events to XMLStreamReader (Stax) events. That is, it acts
 * as an XMLStreamReader, fetching the underlying data from a PullProvider.
 * 

* A PullProvider may provide access to any XDM sequence, whereas an XMLStreamReader always * reads a document. The conversion of a sequence to a document follows the rules for * "normalizing" a sequence in the Serialization specification: for example, atomic values are * converted into text nodes, with adjacent atomic values being space-separated. */ public class PullToStax implements XMLStreamReader { private PullNamespaceReducer provider; private NamePool namePool; private boolean previousAtomic; private FastStringBuffer currentTextNode = new FastStringBuffer(100); private int currentStaxEvent; private XPathException pendingException = null; /** * Create a PullToStax instance, which wraps a Saxon PullProvider as a Stax XMLStreamReader * @param provider the Saxon PullProvider from which the events will be read */ public PullToStax(PullProvider provider) { if (provider instanceof PullNamespaceReducer) { this.provider = (PullNamespaceReducer)provider; } else { this.provider = new PullNamespaceReducer(provider); } namePool = provider.getPipelineConfiguration().getConfiguration().getNamePool(); } public int getAttributeCount() { try { return provider.getAttributes().getLength(); } catch (XPathException e) { pendingException = e; return 0; } } public boolean isAttributeSpecified(int i) { return true; } public QName getAttributeName(int i) { try { AttributeCollection atts = provider.getAttributes(); return new QName(atts.getURI(i), atts.getLocalName(i), atts.getPrefix(i)); } catch (XPathException e) { pendingException = e; return new QName("http://saxon.sf.net/error", "error", ""); } } public String getAttributeLocalName(int i) { try { return provider.getAttributes().getLocalName(i); } catch (XPathException e) { pendingException = e; return "error"; } } public String getAttributeNamespace(int i) { try { return provider.getAttributes().getURI(i); } catch (XPathException e) { pendingException = e; return "http://saxon.sf.net/error"; } } public String getAttributePrefix(int i) { try { return provider.getAttributes().getPrefix(i); } catch (XPathException e) { pendingException = e; return ""; } } public String getAttributeType(int i) { try { AttributeCollection ac = provider.getAttributes(); if (ac.isId(i)) { return "ID"; } else if (ac.isIdref(i)) { return "IDREFS"; } else { return "CDATA"; } } catch (XPathException e) { pendingException = e; return "CDATA"; } } public String getAttributeValue(int i) { try { return provider.getAttributes().getValue(i); } catch (XPathException e) { pendingException = e; return "error"; } } public String getAttributeValue(String uri, String local) { try { return provider.getAttributes().getValue(uri, local); } catch (XPathException e) { pendingException = e; return ""; } } public int getEventType() { return currentStaxEvent; } public int getNamespaceCount() { try { return provider.getNamespaceDeclarations().getNumberOfNamespaces(); } catch (XPathException e) { pendingException = e; return 0; } } public String getText() { if (previousAtomic) { return currentTextNode.toString(); } else { try { return provider.getStringValue().toString(); } catch (XPathException e) { pendingException = e; return ""; } } } public int getTextLength() { if (previousAtomic) { return currentTextNode.length(); } else { try { return provider.getStringValue().length(); } catch (XPathException e) { pendingException = e; return 0; } } } public int getTextStart() { return 0; } public char[] getTextCharacters() { if (previousAtomic) { return currentTextNode.getCharArray(); } else { try { String stringValue = provider.getStringValue().toString(); char[] chars = new char[stringValue.length()]; stringValue.getChars(0, chars.length, chars, 0); return chars; } catch (XPathException e) { pendingException = e; return new char[0]; } } } public int getTextCharacters(int sourceStart, char[] target, int targetStart, int length) throws XMLStreamException { if (pendingException != null) { throw new XMLStreamException(pendingException); } if (previousAtomic) { int end = sourceStart + length; if (end > currentTextNode.length()) { end = currentTextNode.length(); } currentTextNode.getChars(sourceStart, end, target, targetStart); return end - sourceStart; } else { try { String stringValue = provider.getStringValue().subSequence(sourceStart, sourceStart + length).toString(); stringValue.getChars(0, length, target, targetStart); return length; } catch (XPathException e) { pendingException = e; return 0; } } } public int next() throws XMLStreamException { if (pendingException != null) { throw new XMLStreamException(pendingException); } int p; try { p = provider.next(); } catch (XPathException e) { throw new XMLStreamException(e); } switch (p) { case PullProvider.START_OF_INPUT: return next(); case PullProvider.ATOMIC_VALUE: currentTextNode.setLength(0); if (previousAtomic) { currentTextNode.append(' '); } currentTextNode.append(provider.getAtomicValue().getStringValue()); currentStaxEvent = XMLStreamConstants.CHARACTERS; break; case PullProvider.START_DOCUMENT: currentStaxEvent = XMLStreamConstants.START_DOCUMENT; break; case PullProvider.END_DOCUMENT: currentStaxEvent = XMLStreamConstants.END_DOCUMENT; break; case PullProvider.START_ELEMENT: currentStaxEvent = XMLStreamConstants.START_ELEMENT; break; case PullProvider.END_ELEMENT: currentStaxEvent = XMLStreamConstants.END_ELEMENT; break; case PullProvider.TEXT: currentStaxEvent = XMLStreamConstants.CHARACTERS; break; case PullProvider.COMMENT: currentStaxEvent = XMLStreamConstants.COMMENT; break; case PullProvider.PROCESSING_INSTRUCTION: currentStaxEvent = XMLStreamConstants.PROCESSING_INSTRUCTION; break; case PullProvider.END_OF_INPUT: currentStaxEvent = XMLStreamConstants.END_DOCUMENT; break; case PullProvider.ATTRIBUTE: throw new XMLStreamException("Free-standing attributes cannot be serialized"); case PullProvider.NAMESPACE: throw new XMLStreamException("Free-standing namespace nodes cannot be serialized"); default: throw new IllegalStateException("Unknown Stax event " + p); } previousAtomic = (p == PullProvider.ATOMIC_VALUE); return currentStaxEvent; } public int nextTag() throws XMLStreamException { if (pendingException != null) { throw new XMLStreamException(pendingException); } int eventType = next(); while ((eventType == XMLStreamConstants.CHARACTERS && isWhiteSpace()) // skip whitespace || (eventType == XMLStreamConstants.CDATA && isWhiteSpace()) // skip whitespace || eventType == XMLStreamConstants.SPACE || eventType == XMLStreamConstants.PROCESSING_INSTRUCTION || eventType == XMLStreamConstants.COMMENT ) { eventType = next(); } if (eventType != XMLStreamConstants.START_ELEMENT && eventType != XMLStreamConstants.END_ELEMENT) { throw new XMLStreamException("expected start or end tag", getLocation()); } return eventType; } public void close() throws XMLStreamException { if (pendingException != null) { throw new XMLStreamException(pendingException); } provider.close(); } public boolean hasName() { return currentStaxEvent == XMLStreamConstants.START_ELEMENT || currentStaxEvent == XMLStreamConstants.END_ELEMENT; } public boolean hasNext() throws XMLStreamException { if (pendingException != null) { throw new XMLStreamException(pendingException); } return currentStaxEvent != XMLStreamConstants.END_DOCUMENT; } public boolean hasText() { return currentStaxEvent == XMLStreamConstants.CHARACTERS || currentStaxEvent == XMLStreamConstants.COMMENT; } public boolean isCharacters() { return currentStaxEvent == XMLStreamConstants.CHARACTERS; } public boolean isEndElement() { return currentStaxEvent == XMLStreamConstants.END_ELEMENT; } public boolean isStandalone() { return false; } public boolean isStartElement() { return currentStaxEvent == XMLStreamConstants.START_ELEMENT; } public boolean isWhiteSpace() { try { return currentStaxEvent == XMLStreamConstants.CHARACTERS && Whitespace.isWhite(provider.getStringValue()); } catch (XPathException e) { pendingException = e; return false; } } public boolean standaloneSet() { return false; } public String getCharacterEncodingScheme() { return null; } public String getElementText() throws XMLStreamException { if (pendingException != null) { throw new XMLStreamException(pendingException); } if (getEventType() != XMLStreamConstants.START_ELEMENT) { throw new XMLStreamException("parser must be on START_ELEMENT to read next text", getLocation()); } int eventType = next(); StringBuffer content = new StringBuffer(); while (eventType != XMLStreamConstants.END_ELEMENT) { if (eventType == XMLStreamConstants.CHARACTERS || eventType == XMLStreamConstants.CDATA || eventType == XMLStreamConstants.SPACE || eventType == XMLStreamConstants.ENTITY_REFERENCE) { content.append(getText()); } else if (eventType == XMLStreamConstants.PROCESSING_INSTRUCTION || eventType == XMLStreamConstants.COMMENT) { // skipping } else if (eventType == XMLStreamConstants.END_DOCUMENT) { throw new XMLStreamException("unexpected end of document when reading element text content", getLocation()); } else if (eventType == XMLStreamConstants.START_ELEMENT) { throw new XMLStreamException("element text content may not contain START_ELEMENT", getLocation()); } else { throw new XMLStreamException("Unexpected event type " + eventType, getLocation()); } eventType = next(); } return content.toString(); } public String getEncoding() { return null; } public String getLocalName() { return namePool.getLocalName(provider.getNameCode()); } public String getNamespaceURI() { return namePool.getURI(provider.getNameCode()); } public String getPIData() { if (currentStaxEvent != XMLStreamConstants.PROCESSING_INSTRUCTION) { throw new IllegalStateException("Not positioned at a processing instruction"); } try { return provider.getStringValue().toString(); } catch (XPathException e) { pendingException = e; return ""; } } public String getPITarget() { if (currentStaxEvent != XMLStreamConstants.PROCESSING_INSTRUCTION) { throw new IllegalStateException("Not positioned at a processing instruction"); } return namePool.getLocalName(provider.getNameCode()); } public String getPrefix() { return namePool.getPrefix(provider.getNameCode()); } public String getVersion() { return "1.0"; } public String getNamespacePrefix(int i) { try { return provider.getNamespaceDeclarations().getPrefix(i); } catch (XPathException e) { pendingException = e; return ""; } } public String getNamespaceURI(int i) { try { return provider.getNamespaceDeclarations().getURI(i); } catch (XPathException e) { pendingException = e; return ""; } } public NamespaceContext getNamespaceContext() { return new NamespaceContextImpl(provider); } public QName getName() { int nc = provider.getNameCode(); return new QName(namePool.getURI(nc), namePool.getLocalName(nc), namePool.getPrefix(nc)); } public Location getLocation() { SourceLocator sourceLocator = provider.getSourceLocator(); if (sourceLocator == null) { sourceLocator = new ExpressionLocation(); } return new SourceStreamLocation(sourceLocator); } public Object getProperty(String s) throws IllegalArgumentException { return null; //TODO: implement this method } public void require(int event, String uri, String local) throws XMLStreamException { if (pendingException != null) { throw new XMLStreamException(pendingException); } if (currentStaxEvent != event) { throw new XMLStreamException("Required event type is " + event + ", actual event is " + currentStaxEvent); } if (uri != null && !uri.equals(getNamespaceURI())) { throw new XMLStreamException("Required namespace is " + uri + ", actual is " + getNamespaceURI()); } if (local != null && !local.equals(getLocalName())) { throw new XMLStreamException("Required local name is " + local + ", actual is " + getLocalName()); } } public String getNamespaceURI(String s) { return provider.getURIForPrefix(s, true); } /** * Bridge a SAX SourceLocator to a javax.xml.stream.Location */ public class SourceStreamLocation implements javax.xml.stream.Location { private SourceLocator locator; /** * Create a StAX SourceStreamLocation object based on a given SAX SourceLocator * @param locator the SAX SourceLocator */ public SourceStreamLocation(SourceLocator locator) { this.locator = locator; } public int getCharacterOffset() { return -1; } public int getColumnNumber() { return locator.getColumnNumber(); } public int getLineNumber() { return locator.getLineNumber(); } public String getPublicId() { return locator.getPublicId(); } public String getSystemId() { return locator.getSystemId(); } } } // // The contents of this file are subject to the Mozilla Public License Version 1.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.mozilla.org/MPL/ // // Software distributed under the License is distributed on an "AS IS" basis, // WITHOUT WARRANTY OF ANY KIND, either express or implied. // See the License for the specific language governing rights and limitations under the License. // // The Original Code is: all this file // // The Initial Developer of the Original Code is Michael H. Kay. // // Contributor(s): //





© 2015 - 2025 Weber Informatics LLC | Privacy Policy