1 /************************************************************************
3 ** Copyright (C) 2010 Strahinja Markovic
5 ** This file is part of FlightCrew.
7 ** FlightCrew is free software: you can redistribute it and/or modify
8 ** it under the terms of the GNU Lesser General Public License as published
9 ** by the Free Software Foundation, either version 3 of the License, or
10 ** (at your option) any later version.
12 ** FlightCrew is distributed in the hope that it will be useful,
13 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 ** GNU Lesser General Public License for more details.
17 ** You should have received a copy of the GNU Lesser General Public License
18 ** along with FlightCrew. If not, see <http://www.gnu.org/licenses/>.
20 *************************************************************************/
22 #include <xercesc/internal/XMLScanner.hpp>
23 #include <xercesc/dom/DOMNamedNodeMap.hpp>
24 #include "LocationAwareDOMParser.h"
25 #include "LocationInfoDataHandler.h"
27 // This can't be a member variable of the parser since it needs to be around
28 // even after the parser is destroyed. The cleanup methods of the parser's
29 // super class call the handle() method of the handler.
30 // We only ever need a single handler and a const one at that... this could
31 // also easily go into a singleton, but this approach is simpler.
32 static const XercesExt::LocationInfoDataHandler LOCATION_DATA_HANDLER;
33 const char *LOCATION_INFO_KEY = "LocationInfoKey";
34 typedef unsigned int uint;
39 LocationAwareDOMParser::LocationAwareDOMParser( xc::XMLValidator *const valToAdopt,
40 xc::MemoryManager *const manager,
41 xc::XMLGrammarPool *const gramPool )
43 xc::XercesDOMParser( valToAdopt, manager, gramPool )
45 m_LocationInfoKey = xc::XMLString::transcode( LOCATION_INFO_KEY );
49 LocationAwareDOMParser::~LocationAwareDOMParser()
51 xc::XMLString::release( &m_LocationInfoKey );
55 void LocationAwareDOMParser::startElement( const xc::XMLElementDecl &elemDecl,
56 const unsigned int uriId,
57 const XMLCh *const prefixName,
58 const xc::RefVectorOf< xc::XMLAttr > &attrList,
59 const XMLSize_t attrCount,
63 xc::XercesDOMParser::startElement(
64 elemDecl, uriId, prefixName, attrList, attrCount, isEmpty, isRoot );
66 const xc::Locator* locator = getScanner()->getLocator();
67 int line_number = (int) locator->getLineNumber();
68 int column_number = (int) locator->getColumnNumber();
70 xc::DOMNode *current_node = getCurrentNode();
72 // It's OK to const_cast the handler since the parser will only ever
73 // call the handler's handle() method, which doesn't mutate the handler.
74 // In fact, this function not accepting a const handler is probably a design
75 // error on the part of Xerces developers.
76 current_node->setUserData(
78 new NodeLocationInfo( line_number, column_number ),
79 const_cast< XercesExt::LocationInfoDataHandler* >( &LOCATION_DATA_HANDLER ) );
81 // Attribute nodes get the same location as the opening tag
82 // of the element they were declared in... it's the best we can do.
83 xc::DOMNamedNodeMap *attribute_map = current_node->getAttributes();
\r
84 if ( !attribute_map )
\r
88 for ( uint i = 0; i < attribute_map->getLength(); ++i )
\r
90 attribute_map->item( i )->setUserData(
92 new NodeLocationInfo( line_number, column_number ),
93 const_cast< XercesExt::LocationInfoDataHandler* >( &LOCATION_DATA_HANDLER ) );