📄 saxfilter.java
字号:
/* Sesame - Storage and Querying architecture for RDF and RDF Schema * Copyright (C) 2001-2005 Aduna * * Contact: * Aduna * Prinses Julianaplein 14 b * 3817 CS Amersfoort * The Netherlands * tel. +33 (0)33 465 99 87 * fax. +33 (0)33 465 99 87 * * http://aduna.biz/ * http://www.openrdf.org/ * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */package org.openrdf.rio.rdfxml;import java.util.ArrayList;import java.util.HashMap;import java.util.Iterator;import java.util.List;import java.util.Map;import java.util.Stack;import org.xml.sax.Attributes;import org.xml.sax.ContentHandler;import org.xml.sax.Locator;import org.xml.sax.SAXException;import org.openrdf.util.uri.URI;import org.openrdf.util.xml.XmlUtil;import org.openrdf.vocabulary.RDF;import org.openrdf.rio.NamespaceListener;import org.openrdf.rio.ParseLocationListener;/** * A filter on SAX events to make life easier on the RDF parser * itself. This filter does things like combining a call to * startElement() that is directly followed by a call to * endElement() to a single call to emptyElement(). **/class SAXFilter implements ContentHandler {/*----------+| Variables |+----------*/ /** * The RDF parser to supply the filtered SAX events to. **/ private RdfXmlParser _rdfParser; /** * A Locator indicating a position in the text that is currently being * parsed by the SAX parser. **/ private Locator _locator; /** * A listener that is interested in the progress of the SAX parser. **/ private ParseLocationListener _locListener; /** * A listener that is interested in the namespaces that are defined in the * parsed RDF. **/ private NamespaceListener _nsListener; /** * Stack of ElementInfo objects. **/ private Stack _elInfoStack = new Stack(); /** * StringBuffer used to collect text during parsing. **/ private StringBuffer _charBuf = new StringBuffer(512); /** * The document's URI. **/ private URI _documentURI; /** * Flag indicating whether the parser parses stand-alone RDF documents. In * stand-alone documents, the rdf:RDF element is optional if it contains * just one element. **/ private boolean _parseStandAloneDocuments = false; /** * Variable used to defer reporting of start tags. Reporting start tags is * deferred to be able to combine a start tag and an immediately following * end tag to a single call to emptyElement(). **/ private ElementInfo _deferredElement = null; /** * New namespace mappings that have been reported for the next start tag by * the SAX parser, but that are not yet assigned to an ElementInfo object. **/ private Map _newNamespaceMappings = new HashMap(); /** * Flag indicating whether we're currently parsing RDF elements. **/ private boolean _inRdfContext; /** * The number of elements on the stack that are in the RDF context. **/ private int _rdfContextStackHeight; /** * Flag indicating whether we're currently parsing an XML literal. **/ private boolean _parseLiteralMode = false; /** * The number of elements on the stack that are part of an XML literal. **/ private int _xmlLiteralStackHeight; /** * The prefixes that are defined in the XML literal itself (this in contrast * to the namespaces from the XML literal's context). **/ private List _xmlLiteralPrefixes = new ArrayList(); /** * The prefixes that were used in an XML literal, but that were not defined * in it (but rather in the XML literal's context). **/ private List _unknownPrefixesInXmlLiteral = new ArrayList();/*-------------+| Constructors |+-------------*/ public SAXFilter(RdfXmlParser rdfParser) { _rdfParser = rdfParser; }/*--------+| Methods |+--------*/ public Locator getLocator() { return _locator; } public void setParseLocationListener(ParseLocationListener el) { _locListener = el; if (_locator != null) { _locListener.parseLocationUpdate( _locator.getLineNumber(), _locator.getColumnNumber()); } } public ParseLocationListener getParseLocationListener() { return _locListener; } public void setNamespaceListener(NamespaceListener nl) { _nsListener = nl; } public NamespaceListener getNamespaceListener() { return _nsListener; } public void clear() { _locator = null; _elInfoStack.clear(); _charBuf.setLength(0); _documentURI = null; _deferredElement = null; _newNamespaceMappings.clear(); _inRdfContext = false; _rdfContextStackHeight = 0; _parseLiteralMode = false; _xmlLiteralStackHeight = 0; _xmlLiteralPrefixes.clear(); _unknownPrefixesInXmlLiteral.clear(); } public void setDocumentURI(String documentURI) { _documentURI = _createBaseURI(documentURI); } public void setParseStandAloneDocuments(boolean standAloneDocs) { _parseStandAloneDocuments = standAloneDocs; } public boolean getParseStandAloneDocuments() { return _parseStandAloneDocuments; }/*--------------------------------------+| Methods from interface ContentHandler |+--------------------------------------*/ public void setDocumentLocator(Locator locator) { _locator = locator; if (_locListener != null) { _locListener.parseLocationUpdate( locator.getLineNumber(), locator.getColumnNumber()); } } public void startDocument() { // ignore } public void endDocument() { // ignore } public void startPrefixMapping(String prefix, String uri) throws SAXException { if (_deferredElement != null) { // This new prefix mapping must come from a new start tag _reportDeferredStartElement(); } _newNamespaceMappings.put(prefix, uri); if (_parseLiteralMode) { // This namespace is introduced inside an XML literal _xmlLiteralPrefixes.add(prefix); } if (_nsListener != null) { _nsListener.handleNamespace(prefix, uri); } } public void endPrefixMapping(String prefix) { if (_parseLiteralMode) { _xmlLiteralPrefixes.remove(prefix); } } public void startElement(String namespaceURI, String localName, String qName, Attributes attributes) throws SAXException { if (_deferredElement != null) { // The next call could set _parseLiteralMode to true! _reportDeferredStartElement(); } if (_parseLiteralMode) { _appendStartTag(qName, attributes); _xmlLiteralStackHeight++; } else { ElementInfo parent = _peekStack(); ElementInfo elInfo = new ElementInfo(parent, qName, namespaceURI, localName); elInfo.setNamespaceMappings(_newNamespaceMappings); _newNamespaceMappings.clear(); if (!_inRdfContext && _parseStandAloneDocuments && (!localName.equals("RDF") || !namespaceURI.equals(RDF.NAMESPACE))) { // Stand-alone document that does not start with an rdf:RDF root // element. Assume this root element is omitted. _inRdfContext = true; } if (!_inRdfContext) { // Check for presence of xml:base and xlm:lang attributes. for (int i = 0; i < attributes.getLength(); i++) { String attQName = attributes.getQName(i); if ("xml:base".equals(attQName)) { elInfo.setBaseURI( attributes.getValue(i) ); } else if ("xml:lang".equals(attQName)) { elInfo.xmlLang = attributes.getValue(i); } } _elInfoStack.push(elInfo); // Check if we are entering RDF context now. if (localName.equals("RDF") && namespaceURI.equals(RDF.NAMESPACE)) { _inRdfContext = true; _rdfContextStackHeight = 0; } } else { // We're parsing RDF elements. _checkAndCopyAttributes(attributes, elInfo); // Don't report the new element to the RDF parser just yet. _deferredElement = elInfo; } } } private void _reportDeferredStartElement() throws SAXException {/* // Only useful for debugging. if (_deferredElement == null) { throw new RuntimeException("no deferred start element available"); }*/ _elInfoStack.push(_deferredElement); _rdfContextStackHeight++; _rdfParser.setBaseURI(_deferredElement.baseURI); _rdfParser.setXmlLang(_deferredElement.xmlLang); _rdfParser.startElement( _deferredElement.namespaceURI, _deferredElement.localName, _deferredElement.qName, _deferredElement.atts); _deferredElement = null; } public void endElement(String namespaceURI, String localName, String qName) throws SAXException { // FIXME: in parseLiteralMode we should also check // if start- and end-tags match. if (_rdfParser._verifyData && !_parseLiteralMode) { // Verify that the end tag matches the start tag. ElementInfo elInfo; if (_deferredElement != null) { elInfo = _deferredElement; } else { elInfo = _peekStack();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -