/* * $Revision: 2564 $ * * last checkin: * $Author: gutwenger $ * $Date: 2012-07-07 00:03:48 +0200 (Sa, 07. Jul 2012) $ ***************************************************************/ /** \file * \brief Contains the struct declarations XmlAttributeObject, XmlTagObject * and the class DinoXmlParser. * * \author Dino Ahr * * \par License: * This file is part of the Open Graph Drawing Framework (OGDF). * * \par * Copyright (C)
* See README.txt in the root directory of the OGDF installation for details. * * \par * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * Version 2 or 3 as published by the Free Software Foundation; * see the file LICENSE.txt included in the packaging of this file * for details. * * \par * This program 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 General Public License for more details. * * \par * You should have received a copy of the GNU General Public * License along with this program; if not, write to the Free * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * \see http://www.gnu.org/copyleft/gpl.html ***************************************************************/ #ifdef _MSC_VER #pragma once #endif #ifndef OGDF_DINO_XML_PARSER_H #define OGDF_DINO_XML_PARSER_H #include "../basic/Stack.h" #include "../basic/String.h" #include "../basic/Hashing.h" #include "../basic/GraphAttributes.h" #include "DinoXmlScanner.h" namespace ogdf { //--------------------------------------------------------- // H a s h e d S t r i n g //--------------------------------------------------------- typedef HashElement HashedString; //--------------------------------------------------------- // X m l A t t r i b u t e O b j e c t //--------------------------------------------------------- /** This struct represents an attribute associated to a tag. */ struct OGDF_EXPORT XmlAttributeObject { /** Contains the name of the attribute, i.e. * for ... it contains "attr1" */ HashedString *m_pAttributeName; /** Contains the value assigned to this attribute without qoutes, i.e. * for ... it contains "value1" and not "\"value1\"". */ HashedString *m_pAttributeValue; /** Pointer to the next attribute and 0 if this is the only attribute. */ XmlAttributeObject *m_pNextAttribute; /** Constructor */ XmlAttributeObject(HashedString *name, HashedString *value) : m_pAttributeName(name), m_pAttributeValue(value), m_pNextAttribute(0) {}; /** Destructor; will be performed in destroyParseTree(). */ ~XmlAttributeObject(){}; /** Flag denotes whether attribute is valid or not. */ bool m_valid; /** Getter. */ const String& getName() const { return m_pAttributeName->key(); } const String& getValue() const { return m_pAttributeValue->key(); } const bool& valid() const { return m_valid; } /** Setter. */ void setValid() { m_valid = true; } void setInvalid() { m_valid = false; } // Overloaded new and delete operators OGDF_NEW_DELETE }; // struct XmlAttributeObject //--------------------------------------------------------- // X m l T a g O b j e c t //--------------------------------------------------------- /** This struct represents a node in the XML parse tree. */ struct OGDF_EXPORT XmlTagObject { /** The identifier of the tag, *i.e. for the identifier is "A" */ HashedString *m_pTagName; /** Pointer to the first attribute; * if there is more than one attribute these are linked by * m_pNextAttribute in struct XmlAttributeObject */ XmlAttributeObject *m_pFirstAttribute; /** Contains the characters inbetween the start tag and the end tag, * i.e. for lala it contains " lala " */ HashedString *m_pTagValue; /** Contains the pointer to the first son tag object, * i.e. for ... ... it contains a pointer * to the object representing B * The other children of A are reachable via m_pBrother of the first son, * i.e. the variable m_pBrother of the object representing B contains a * pointer to the object representing C */ XmlTagObject *m_pFirstSon; /** Contains the pointer to a brother tag object or 0 if this * object is the only child */ XmlTagObject *m_pBrother; /** Constructor */ XmlTagObject(HashedString *name) : m_pTagName(name), m_pFirstAttribute(0), m_pTagValue(0), m_pFirstSon(0), m_pBrother(0), m_valid(0) {}; /** Destructor; will be performed in destroyParseTree(). */ ~XmlTagObject(){}; /** Flag denotes whether attribute is valid or not. */ mutable bool m_valid; /** integer value for the depth in the xml parse tree */ int m_depth; /** integer value that stores the line number * of the tag in the parsed xml document */ int m_line; public: /**Checks if currentNode is leaf in the parse tree. * Returns true if list of sons is empty. * Returns false otherwise. * * NEW */ bool isLeaf() const; /**Searches for a son with tag name sonsName. * Returns the son via the referenced pointer son. * Returns true if son is found. * Returns false, otherwise, son is set to NULL. * * NEW */ bool findSonXmlTagObjectByName( const String sonsName, XmlTagObject *&son) const; /**Searches for sons with tag name sonsName. * Returns the sons via a list with pointers to the sons. * Returns true if at least one son was found. * Returns false otherwise, sons is set to NULL. * * NEW */ bool findSonXmlTagObjectByName( const String sonsName, List &sons) const; /**Searches for sons of father which names are inequal to those * in list sonsNames. * Returns true if at least one son of father is found whose name * doesn't match one in sonsNames. * Returns false otherwise. * * NEW */ bool hasMoreSonXmlTagObject(const List &sonNamesToIgnore) const; /**Searches for an attribute with name name. * * NEW */ bool findXmlAttributeObjectByName( const String attName, XmlAttributeObject*& attribute) const; /**Checks if currentTag owns at least one attribute. * Returns true if list of attributes isn't empty. * Returns false otherwise. * * NEW */ bool isAttributeLess() const; /** Getter. */ const bool& valid() const { return m_valid; } const String& getName() const { return m_pTagName->key(); } const String& getValue() const { return m_pTagValue->key(); } /** Setter. */ void setValid() const { m_valid = true; } void setInvalid() { m_valid = false; } /* get for depth of xml-tag-object */ const int& getDepth() const { return m_depth; } /* setter for new depth */ void setDepth(int newDepth){ m_depth = newDepth; } /* get for line of xml-tag-object */ const int& getLine() const { return m_line; } /* setter for line */ void setLine(int line) { m_line = line; } // Overloaded new and delete operators OGDF_NEW_DELETE }; // struct XmlTagObject //--------------------------------------------------------- // D i n o X m l P a r s e r //--------------------------------------------------------- /** This class parses the XML input file and builds up a * parse tree with linked elements XMLTagObject and * XMLAttributeObject. The class DinoXmlScanner is used to * get the token for the parse process. */ class OGDF_EXPORT DinoXmlParser { friend ostream &operator<<(ostream&, const DinoXmlParser &); private: /** Pointer to the root element of the parse tree. */ XmlTagObject *m_pRootTag; /** Pointer to the scanner. */ DinoXmlScanner *m_pScanner; /** Hash table for storing names of TagObjects and * AttributeObjects in an efficient manner. * The key element is String. * The info element is int. */ Hashing m_hashTable; /** The info element of the hash table is simply an integer * number which is incremented for each new element (starting at 0). * The value m_hashTableInfoIndex - 1 is the last used index. */ int m_hashTableInfoIndex; /** Recursion depth of parse(). */ int m_recursionDepth; /** stack for checking correctness of correspondent closing tags */ Stack m_tagObserver; public: /** Constructor. * Inside the constructor the scanner is generated. */ DinoXmlParser(const char *fileName); /** Destructor; destroys the parse tree. */ ~DinoXmlParser(); /** Creates a new hash element and inserts it into the hash table. */ void addNewHashElement(const String &key, int info){ OGDF_ASSERT(info >= m_hashTableInfoIndex) m_hashTable.fastInsert(key, info); m_hashTableInfoIndex = info + 1; } /** Creates the parse tree and anchors it in m_pRootTag. * TODO: Should return a value to indicate if success. */ void createParseTree(); /** Allows (non modifying) access to the parse tree. */ const XmlTagObject &getRootTag() const { return *m_pRootTag; } /** Traverses the parseTree starting at startTag using the path * description in path, which contains the infoIndices of the tags * which have to be traversed. * If the XmlTagObject associated to the last infoIndex in the path is * found, it is returned via targetTag and the return value is true * If the XmlTagObject is not found the return value is false. */ bool traversePath( const XmlTagObject &startTag, const Array &infoIndexPath, const XmlTagObject *&targetTag) const; /** Searches for a specific son (identified by sonInfoIndex) * of father. * Returns the son via the referenced pointer son. * Returns true if son is found. * Returns false otherwise, son is set to NULL. */ bool findSonXmlTagObject( const XmlTagObject &father, int sonInfoIndex, const XmlTagObject *&son) const; /** Searches for a specific brother (identified by brotherInfoIndex) * of current. * Returns the brother via the referenced pointer brother. * Returns true if brother is found. * Returns false otherwise, brother is set to NULL. */ bool findBrotherXmlTagObject( const XmlTagObject ¤tTag, int brotherInfoIndex, const XmlTagObject *&brother) const; /** Searches for a specific attribute (identified by attributeInfoIndex) * of current. * Returns the attribute via the referenced pointer attribute. * Returns true if attribute is found. * Returns false otherwise, attribute is set to NULL. */ bool findXmlAttributeObject( const XmlTagObject ¤tTag, int attributeInfoIndex, const XmlAttributeObject *&attribute) const; /** Returns line number of the most recently read line of * the input file. */ inline int getInputFileLineCounter() const { return m_pScanner->getInputFileLineCounter(); } /** Prints the content of the hash table to os. */ void printHashTable(ostream &os); private: /** Destroys the parse tree appended to root. */ void destroyParseTree(XmlTagObject *root); /** Parses the token stream provided by the scanner until a complete * XmlTagObject is identified which will be returned. * This function is likely to be called recursively * due to the recursive structure of XML documents. */ XmlTagObject* parse(); /** Append attributeObject to list of attributes of tagObject. */ void appendAttributeObject( XmlTagObject *tagObject, XmlAttributeObject *attributeObject); /** Appends sonTagObject to the list of sons of currentTagObject. */ void appendSonTagObject( XmlTagObject *currentTagObject, XmlTagObject *sonTagObject); /** Returns the hash element for the given string. * If the key str is not contained in the table yet, it is * inserted together with a new info index and the new * hash element is returned. * If the key str exists, the associated hash element is returned. */ HashedString *hashString(const String &str); /** Prints the given XmlTagObject and its children recursively. * The parameter indent is used as indentation value. */ void printXmlTagObjectTree( ostream &os, const XmlTagObject &rootObject, int indent = 0) const; /** Little helper that prints nOfSpaces space characters. */ void printSpaces(ostream &os, int nOfSpaces) const; }; // class DinoXmlParser /** Output operator for DinoXmlParser. */ ostream &operator<<(ostream &os, const DinoXmlParser &parser); } // end namespace ogdf #endif