18 _current(NULL) , _fileName( fileName ), _forCCheck( forCCheck ) {
34 str <<
"XMLParser::parse error in file [" <<
_fileName
44 if( root==0 || strcmp(root->
Value(),
"marlin") != 0 ){
63 _map[
"Global" ] = std::make_shared<StringParameters>();
80 const char* attr = p->Attribute(
"name" );
82 if( attr != 0 &&
std::string( attr ) ==
"OutputSteeringFile" ) {
89 p->SetAttribute(
"value" ,
"" );
100 activeProcs.
push_back(
"ActiveProcessors") ;
103 procConds.
push_back(
"ProcessorConditions") ;
120 while( ( proc = section->
IterateChildren(
"processor", proc ) ) != 0 ){
128 if( procList.
find( procName ) != procList.
end() ){
131 procList.
insert( procName ) ;
139 if( condition.
size() == 0 )
140 condition +=
"true" ;
163 while((section = nextSection) != 0){
169 while( ( param = section->
IterateChildren(
"parameter" , param ) ) != 0 ){
174 while( ( proc = section->
IterateChildren(
"processor" , proc ) ) != 0 ){
193 availableProcs.
push_back(
"AvailableProcessors") ;
198 unsigned procCount(0) ;
199 unsigned typedProcCount(0) ;
204 while( (section = root->
IterateChildren(
"processor", section ) ) != 0 ){
209 _map[ name ] = std::make_shared<StringParameters>();
213 if( procList.
find( name ) != procList.
end() ){
225 procType[0] =
"ProcessorType" ;
227 _current->add( procType ) ;
245 globalParameters->add( availableProcs ) ;
252 std::cout <<
"---------------------------------------------------------------------" <<
std::endl
253 <<
" WARNING XMLParser : none of the available processors have input or " <<
std::endl
254 <<
" or output collection information assigned. You won't be able to " <<
std::endl
255 <<
" check the steering file for consistency with 'Marlin -c steer.xml'" <<
std::endl
256 <<
" Please use Processor::registerInputCollection() and " <<
std::endl
257 <<
" Processor::registerOutputCollection() in you Marlin processors " <<
std::endl
258 <<
" and create a new steering file with 'Marlin -x > newsteer.xml' " <<
std::endl
259 <<
" or add the appropriate information to your existing steering files " <<
std::endl
260 <<
"---------------------------------------------------------------------" <<
std::endl ;
282 str <<
"Unknwon command line parameter overwrite ( spelling !?) : \n " ;
284 typedef CommandLineParametersMap::iterator IT ;
290 typedef CommandLineParametersMap::mapped_type ValMap ;
292 ValMap* clp_map = &itP->second ;
294 for( ValMap::iterator it = clp_map->begin() , end = clp_map->end() ; it!=end ; ++it ) {
295 str <<
" " << index1 <<
"." << it->first <<
" : " << it->second <<
"\n" ;
299 str <<
" Note: only parameters that are present in the Marlin steering file can be overwritten !!! " <<
"\n" ;
309 throw ParseException(
"XMLParser::write: file not opened. Couldn't write to disk !" );
319 throw ParseException(
"XMLParser::getAttribute not an XMLElement " ) ;
326 str <<
"XMLParser::getAttribute missing attribute \"" << name
327 <<
"\" in element <" << el->
Value() <<
"/> in file " <<
_fileName ;
347 index1 = section->
Value() ;
348 if( index1.
compare(
"processor" ) == 0 ){
353 typedef CommandLineParametersMap::mapped_type ValMap ;
354 ValMap* clp_map = 0 ;
357 clp_map = &( clp_it->second ) ;
413 ValMap::iterator vm_it = clp_map->find( index2 ) ;
415 if( vm_it != clp_map->end() ) {
417 cmdlinevalues = vm_it->second ;
419 if( cmdlinevalues.
compare(
"" ) != 0 ){
421 inputLine = cmdlinevalues ;
425 clp_map->
erase( vm_it ) ;
447 std::cout <<
"XMLParser::parse : Couldn't parse parameter \"" << name <<
"\"" <<
std::endl ;
469 lcioInTypes.
push_back(
"_marlin.lcioInType" ) ;
470 lcioOutTypes.
push_back(
"_marlin.lcioOutType" ) ;
502 if( clp_map != 0 && clp_map->size() == 0 ) {
520 return _map[ sectionName ] ;
528 if( aCondition.
find(
'&') != std::string::npos || aCondition.
find(
'|') != std::string::npos )
529 condition =
"(" + aCondition +
")" ;
531 condition = aCondition ;
535 while((child = nextChild) != 0){
540 while( ( child = current->
IterateChildren(
"processor" , child ) ) != 0 ) {
551 if( cond.size() > 0 && condition.
size() )
633 str <<
"XMLParser::processIncludeElement missing attribute \"" <<
"ref"
634 <<
"\" in element <" << element->
Value() <<
"/> in file " <<
_fileName ;
643 std::cout <<
"XMLParser::processIncludeElement : Couldn't parse include ref \"" << ref <<
"\"" <<
std::endl ;
647 if( ref.size() < 5 || ref.substr( ref.size() - 4 ) !=
".xml" ) {
650 str <<
"XMLParser::processIncludeElement invalid ref file name \"" << ref
651 <<
"\" in element <" << element->
Value() <<
"/> in file " <<
_fileName ;
657 if( ref.at(0) !=
'/' ) {
664 if( idx != std::string::npos )
669 refFileName = baseFileName + ref ;
675 bool loadOkay = document.
LoadFile( refFileName ) ;
680 str <<
"XMLParser::processIncludeElement error in file [" << refFileName
681 <<
", row: " << document.
ErrorRow() <<
", col: " << document.
ErrorCol() <<
"] : "
698 ss <<
"Nested includes are not allowed [in file: " << node->
GetDocument()->
Value() <<
", line: " << child->Row() <<
"] !" ;
757 typedef CommandLineParametersMap::mapped_type ValMap ;
758 ValMap* clp_map = 0 ;
762 clp_map = &( clp_it->second ) ;
766 if( clp_map != 0 && clp_map->size() == 0 ) {
777 typedef CommandLineParametersMap::mapped_type ValMap ;
778 ValMap* clp_map = 0 ;
782 clp_map = &( clp_it->second ) ;
787 throw ParseException(
"XMLParser::processConstant : constant element without name. Skipping ..." ) ;
794 throw ParseException(
"XMLParser::processConstant : parsed empty constant name !" ) ;
799 if( constants.
end() != constants.
find( name ) ) {
801 str <<
"XMLParser::processConstant : constant \"" << name <<
"\" defined twice !" <<
std::endl ;
820 ValMap::iterator vm_it = clp_map->find( name ) ;
822 if( vm_it != clp_map->end() ) {
826 if( cmdlinevalues.
compare(
"" ) != 0 ){
828 value = cmdlinevalues ;
829 clp_map->
erase( vm_it ) ;
849 std::cout <<
"XMLParser::processConstant : Couldn't parse constant \"" << name <<
"\"" <<
std::endl ;
855 str <<
"XMLParser::processConstant : couldn't add constant \"" << name <<
"\" to constant map !" <<
std::endl ;
859 std::cout <<
"Read constant \"" << name <<
"\" , value = \"" << value <<
"\"" <<
std::endl ;
866 size_t pos = value.
find(
"${") ;
869 while( pos != std::string::npos ) {
873 if( pos2 == std::string::npos ) {
875 throw ParseException(
"XMLParser::performConstantReplacement : couldn't parse constant value !" ) ;
879 auto findConstant = constants.
find( key ) ;
880 const std::string replacementValue( findConstant != constants.
end() ? findConstant->second :
"" ) ;
882 if( replacementValue.empty() ) {
885 str <<
"XMLParser::performConstantReplacement : constant \"" << key <<
"\" not found in available constants !" ;
889 value.
replace( pos , (pos2+1-pos) , replacementValue ) ;
890 pos2 = pos + replacementValue.size() ;
892 pos = value.
find(
"${", pos2) ;
903 std::cout <<
"XMLParser::parse : no root tag <marlin>...</marlin> found ! " <<
std::endl ;
909 while((child = nextChild) != 0){
950 bool elementFound = false ;
955 elementFound = true ;
const TiXmlElement * RootElement() const
Get the root element – the only top level element – of the document.
void write(const std::string &filen) const
Write the parsed XML tree in an other file.
ParseException used for parse errors, e.g.
void processIncludeElements(TiXmlElement *element, const std::map< std::string, std::string > &constants)
Helper method - recursively replace all with the corresponding file content.
StringParameters * _current
const char * getAttribute(TiXmlNode *node, const std::string &name)
Return named attribute - throws ParseException if attribute doesn't exist.
void processconditions(TiXmlNode *current, const std::string &conditions)
Helper method - recursively moves processors from <if> tags to top level (<execute>) and adds corresp...
void add(const std::string &key, const std::vector< std::string > &values)
bool LoadFile(TiXmlEncoding encoding=TIXML_DEFAULT_ENCODING)
Load a file using the current document value.
void SetValue(const char *_value)
Changes the value of the node.
int ErrorCol() const
The column where the error occured. See ErrorRow()
TiXmlNode * InsertEndChild(const TiXmlNode &addThis)
Add a new node related to this.
TiXmlNode * InsertBeforeChild(TiXmlNode *beforeThis, const TiXmlNode &addThis)
Add a new node related to this.
Helper class for XMLParser.
int ErrorRow() const
Returns the location (if known) of the error.
const TiXmlNode * FirstChild() const
The first child of this node. Will be null if there are no children.
const char * ErrorDesc() const
Contains a textual (english) description of the error if one occurs.
void SetAttribute(const char *name, const char *_value)
Sets an attribute of name to a given value.
std::shared_ptr< StringParameters > getParameters(const std::string §ionName) const
Return the StringParameters for the section as read from the xml file.
bool SaveFile() const
Save a file using the current document value. Returns true if successful.
std::string & performConstantReplacement(std::string &value, const std::map< std::string, std::string > &constants)
Always the top level node.
const TiXmlElement * FirstChildElement() const
Convenience function to get through elements.
T find_first_of(T...args)
CommandLineParametersMap _cmdlineparams
TiXmlNode * InsertAfterChild(TiXmlNode *afterThis, const TiXmlNode &addThis)
Add a new node related to this.
virtual const TiXmlElement * ToElement() const
Cast to a more defined type. Will return null if not of the requested type.
const TiXmlDocument * GetDocument() const
Return a pointer to the Document this node lives in.
TiXmlNode * findElement(TiXmlNode *node, const std::string &type, const std::string &attribute, const std::string &value)
Helper method - finds child element of node with given type and attribute value.
const TiXmlElement * NextSiblingElement() const
Convenience function to get through elements.
TiXmlNode * Parent()
One step up the DOM.
void parse()
Parse the input file.
The parent class for everything in the Document Object Model.
void processConstant(TiXmlElement *element, std::map< std::string, std::string > &constants)
std::unique_ptr< TiXmlDocument > _doc
const TiXmlNode * IterateChildren(const TiXmlNode *previous) const
An alternate way to walk the children of a node.
const char * Value() const
The meaning of 'value' changes for the specific type of TiXmlNode.
bool RemoveChild(TiXmlNode *removeThis)
Delete a child of this node.
void processConstants(TiXmlNode *node, std::map< std::string, std::string > &constants)
void checkForNestedIncludes(const TiXmlNode *node)
void replacegroups(TiXmlNode *section)
Helper method - replaces all <group> tag with corresponding <processor> tags.
const char * Attribute(const char *name) const
Given an attribute name, Attribute() returns the value for the attribute of that name, or null if none exists.
Simple parameters class for Marlin.
virtual TiXmlNode * Clone() const =0
Create an exact duplicate of this node and return it.
void parametersFromNode(TiXmlNode *section, std::map< std::string, std::string > &constants, std::pair< unsigned, unsigned > *typeCount=0)
Extracts all parameters from the given node and adss them to the current StringParameters object...
void processIncludeElement(TiXmlElement *element, const std::map< std::string, std::string > &constants, TiXmlDocument &document)
The element is a container class.