/* * 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 parser.extension; import java.util.Map; import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import org.xml.sax.Attributes; import org.xml.sax.Locator; import org.xml.sax.SAXException; import org.xml.sax.XMLReader; import groovy.util.Node; import groovy.util.XmlParser; import groovy.xml.QName; /** * Extend XmlParser class to support recording the location * (file name, line number, column number) * of every element created, so that later processing can issue * error messages about the XML and refer to the file, line, col * where the user should look. * * Also - convert the element names (which are in this application QNames * because namespaces are used) and convert them to plain strings without * the namesapces. * */ public class XmlParserExt extends XmlParser { // Delegate the constructors (only some of them which were used in this app are here) public XmlParserExt() throws ParserConfigurationException, SAXException { this(false, true); } public XmlParserExt(boolean validating, boolean namespaceAware) throws ParserConfigurationException, SAXException { super(validating, namespaceAware); } public XmlParserExt(SAXParser parser) throws SAXException { super(parser); } public XmlParserExt(XMLReader reader) { super(reader); } // Override the newNodeInstance to create the subtype of Node having location info protected Node newNodeInstance(Node parent, Object name, Map attributes, Object value) { return new NodeWithLoc(parent, name, attributes, value); } // Override the startElement to capture the location information from the parser and // add it to the created node // Also, modify the name to be a plain string, the local part of the qname public void startElement(String namespaceURI, String localName, String qName, Attributes list) throws SAXException { super.startElement(namespaceURI, localName, qName, list); Locator el = getDocumentLocator(); NodeWithLoc node = ((NodeWithLoc)getParent()); node.setPublicId(el.getPublicId()); node.setSystemId(el.getSystemId()); node.setLineNbr(el.getLineNumber()); node.setColNbr(el.getColumnNumber()); // strip namespace stuff, too getParent().setName(((QName)getParent().name()).getLocalPart()); } }