6 * $Date: 2012-07-07 00:03:48 +0200 (Sa, 07. Jul 2012) $
7 ***************************************************************/
10 * \brief Contains the struct declarations XmlAttributeObject, XmlTagObject
11 * and the class DinoXmlParser.
16 * This file is part of the Open Graph Drawing Framework (OGDF).
20 * See README.txt in the root directory of the OGDF installation for details.
23 * This program is free software; you can redistribute it and/or
24 * modify it under the terms of the GNU General Public License
25 * Version 2 or 3 as published by the Free Software Foundation;
26 * see the file LICENSE.txt included in the packaging of this file
30 * This program is distributed in the hope that it will be useful,
31 * but WITHOUT ANY WARRANTY; without even the implied warranty of
32 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
33 * GNU General Public License for more details.
36 * You should have received a copy of the GNU General Public
37 * License along with this program; if not, write to the Free
38 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
39 * Boston, MA 02110-1301, USA.
41 * \see http://www.gnu.org/copyleft/gpl.html
42 ***************************************************************/
48 #ifndef OGDF_DINO_XML_PARSER_H
49 #define OGDF_DINO_XML_PARSER_H
51 #include <ogdf/basic/Stack.h>
52 #include <ogdf/basic/String.h>
53 #include <ogdf/basic/Hashing.h>
54 #include <ogdf/basic/GraphAttributes.h>
55 #include <ogdf/fileformats/DinoXmlScanner.h>
61 //---------------------------------------------------------
62 // H a s h e d S t r i n g
63 //---------------------------------------------------------
65 typedef HashElement
<String
,int> HashedString
;
67 //---------------------------------------------------------
68 // X m l A t t r i b u t e O b j e c t
69 //---------------------------------------------------------
70 /** This struct represents an attribute associated to a tag.
72 struct OGDF_EXPORT XmlAttributeObject
{
74 /** Contains the name of the attribute, i.e.
75 * for <A attr1="value1"> ... </A> it contains "attr1"
77 HashedString
*m_pAttributeName
;
79 /** Contains the value assigned to this attribute without qoutes, i.e.
80 * for <A attr1="value1"> ... </A> it contains "value1" and not "\"value1\"".
82 HashedString
*m_pAttributeValue
;
84 /** Pointer to the next attribute and 0 if this is the only attribute. */
85 XmlAttributeObject
*m_pNextAttribute
;
88 XmlAttributeObject(HashedString
*name
, HashedString
*value
) :
89 m_pAttributeName(name
),
90 m_pAttributeValue(value
),
94 /** Destructor; will be performed in destroyParseTree(). */
95 ~XmlAttributeObject(){};
97 /** Flag denotes whether attribute is valid or not. */
101 const String
& getName() const {
102 return m_pAttributeName
->key();
105 const String
& getValue() const {
106 return m_pAttributeValue
->key();
109 const bool& valid() const {
122 // Overloaded new and delete operators
125 }; // struct XmlAttributeObject
127 //---------------------------------------------------------
128 // X m l T a g O b j e c t
129 //---------------------------------------------------------
130 /** This struct represents a node in the XML parse tree.
132 struct OGDF_EXPORT XmlTagObject
{
134 /** The identifier of the tag,
135 *i.e. for <A> the identifier is "A"
137 HashedString
*m_pTagName
;
139 /** Pointer to the first attribute;
140 * if there is more than one attribute these are linked by
141 * m_pNextAttribute in struct XmlAttributeObject
143 XmlAttributeObject
*m_pFirstAttribute
;
145 /** Contains the characters inbetween the start tag and the end tag,
146 * i.e. for <A attr1=... attr2=...> lala </A> it contains " lala "
148 HashedString
*m_pTagValue
;
150 /** Contains the pointer to the first son tag object,
151 * i.e. for <A> <B> ... </B> <C> ... </C> </A> it contains a pointer
152 * to the object representing B
153 * The other children of A are reachable via m_pBrother of the first son,
154 * i.e. the variable m_pBrother of the object representing B contains a
155 * pointer to the object representing C
157 XmlTagObject
*m_pFirstSon
;
159 /** Contains the pointer to a brother tag object or 0 if this
160 * object is the only child
162 XmlTagObject
*m_pBrother
;
165 XmlTagObject(HashedString
*name
) :
167 m_pFirstAttribute(0),
174 /** Destructor; will be performed in destroyParseTree(). */
177 /** Flag denotes whether attribute is valid or not. */
178 mutable bool m_valid
;
180 /** integer value for the depth in the xml parse tree */
183 /** integer value that stores the line number
184 * of the tag in the parsed xml document */
189 /**Checks if currentNode is leaf in the parse tree.
190 * Returns true if list of sons is empty.
191 * Returns false otherwise.
197 /**Searches for a son with tag name sonsName.
198 * Returns the son via the referenced pointer son.
199 * Returns true if son is found.
200 * Returns false, otherwise, son is set to NULL.
204 bool findSonXmlTagObjectByName( const String sonsName
,
205 XmlTagObject
*&son
) const;
207 /**Searches for sons with tag name sonsName.
208 * Returns the sons via a list with pointers to the sons.
209 * Returns true if at least one son was found.
210 * Returns false otherwise, sons is set to NULL.
214 bool findSonXmlTagObjectByName( const String sonsName
,
215 List
<XmlTagObject
*> &sons
) const;
217 /**Searches for sons of father which names are inequal to those
219 * Returns true if at least one son of father is found whose name
220 * doesn't match one in sonsNames.
221 * Returns false otherwise.
225 bool hasMoreSonXmlTagObject(const List
<String
> &sonNamesToIgnore
) const;
227 /**Searches for an attribute with name name.
231 bool findXmlAttributeObjectByName(
232 const String attName
,
233 XmlAttributeObject
*& attribute
) const;
235 /**Checks if currentTag owns at least one attribute.
236 * Returns true if list of attributes isn't empty.
237 * Returns false otherwise.
241 bool isAttributeLess() const;
244 const bool& valid() const {
248 const String
& getName() const {
249 return m_pTagName
->key();
252 const String
& getValue() const {
253 return m_pTagValue
->key();
257 void setValid() const {
265 /* get for depth of xml-tag-object */
266 const int& getDepth() const {
270 /* setter for new depth */
271 void setDepth(int newDepth
){
276 /* get for line of xml-tag-object */
277 const int& getLine() const {
281 /* setter for line */
282 void setLine(int line
) {
286 // Overloaded new and delete operators
289 }; // struct XmlTagObject
291 //---------------------------------------------------------
292 // D i n o X m l P a r s e r
293 //---------------------------------------------------------
294 /** This class parses the XML input file and builds up a
295 * parse tree with linked elements XMLTagObject and
296 * XMLAttributeObject. The class DinoXmlScanner is used to
297 * get the token for the parse process.
299 class OGDF_EXPORT DinoXmlParser
{
301 friend ostream
&operator<<(ostream
&, const DinoXmlParser
&);
305 /** Pointer to the root element of the parse tree. */
306 XmlTagObject
*m_pRootTag
;
308 /** Pointer to the scanner. */
309 DinoXmlScanner
*m_pScanner
;
311 /** Hash table for storing names of TagObjects and
312 * AttributeObjects in an efficient manner.
313 * The key element is String.
314 * The info element is int.
316 Hashing
<String
,int> m_hashTable
;
318 /** The info element of the hash table is simply an integer
319 * number which is incremented for each new element (starting at 0).
320 * The value m_hashTableInfoIndex - 1 is the last used index.
322 int m_hashTableInfoIndex
;
324 /** Recursion depth of parse(). */
325 int m_recursionDepth
;
326 /** stack for checking correctness of correspondent closing tags */
327 Stack
<String
> m_tagObserver
;
333 * Inside the constructor the scanner is generated.
335 DinoXmlParser(const char *fileName
);
337 /** Destructor; destroys the parse tree. */
340 /** Creates a new hash element and inserts it into the hash table.
342 void addNewHashElement(const String
&key
, int info
){
343 OGDF_ASSERT(info
>= m_hashTableInfoIndex
)
344 m_hashTable
.fastInsert(key
, info
);
345 m_hashTableInfoIndex
= info
+ 1;
348 /** Creates the parse tree and anchors it in m_pRootTag.
349 * TODO: Should return a value to indicate if success.
351 void createParseTree();
353 /** Allows (non modifying) access to the parse tree. */
354 const XmlTagObject
&getRootTag() const {
358 /** Traverses the parseTree starting at startTag using the path
359 * description in path, which contains the infoIndices of the tags
360 * which have to be traversed.
361 * If the XmlTagObject associated to the last infoIndex in the path is
362 * found, it is returned via targetTag and the return value is true
363 * If the XmlTagObject is not found the return value is false.
366 const XmlTagObject
&startTag
,
367 const Array
<int> &infoIndexPath
,
368 const XmlTagObject
*&targetTag
) const;
370 /** Searches for a specific son (identified by sonInfoIndex)
372 * Returns the son via the referenced pointer son.
373 * Returns true if son is found.
374 * Returns false otherwise, son is set to NULL.
376 bool findSonXmlTagObject(
377 const XmlTagObject
&father
,
379 const XmlTagObject
*&son
) const;
381 /** Searches for a specific brother (identified by brotherInfoIndex)
383 * Returns the brother via the referenced pointer brother.
384 * Returns true if brother is found.
385 * Returns false otherwise, brother is set to NULL.
387 bool findBrotherXmlTagObject(
388 const XmlTagObject
¤tTag
,
389 int brotherInfoIndex
,
390 const XmlTagObject
*&brother
) const;
392 /** Searches for a specific attribute (identified by attributeInfoIndex)
394 * Returns the attribute via the referenced pointer attribute.
395 * Returns true if attribute is found.
396 * Returns false otherwise, attribute is set to NULL.
398 bool findXmlAttributeObject(
399 const XmlTagObject
¤tTag
,
400 int attributeInfoIndex
,
401 const XmlAttributeObject
*&attribute
) const;
403 /** Returns line number of the most recently read line of
406 inline int getInputFileLineCounter() const {
407 return m_pScanner
->getInputFileLineCounter();
410 /** Prints the content of the hash table to os. */
411 void printHashTable(ostream
&os
);
415 /** Destroys the parse tree appended to root. */
416 void destroyParseTree(XmlTagObject
*root
);
418 /** Parses the token stream provided by the scanner until a complete
419 * XmlTagObject is identified which will be returned.
420 * This function is likely to be called recursively
421 * due to the recursive structure of XML documents.
423 XmlTagObject
* parse();
425 /** Append attributeObject to list of attributes of tagObject. */
426 void appendAttributeObject(
427 XmlTagObject
*tagObject
,
428 XmlAttributeObject
*attributeObject
);
430 /** Appends sonTagObject to the list of sons of currentTagObject. */
431 void appendSonTagObject(
432 XmlTagObject
*currentTagObject
,
433 XmlTagObject
*sonTagObject
);
435 /** Returns the hash element for the given string.
436 * If the key str is not contained in the table yet, it is
437 * inserted together with a new info index and the new
438 * hash element is returned.
439 * If the key str exists, the associated hash element is returned.
441 HashedString
*hashString(const String
&str
);
443 /** Prints the given XmlTagObject and its children recursively.
444 * The parameter indent is used as indentation value.
446 void printXmlTagObjectTree(
448 const XmlTagObject
&rootObject
,
449 int indent
= 0) const;
451 /** Little helper that prints nOfSpaces space characters. */
452 void printSpaces(ostream
&os
, int nOfSpaces
) const;
454 }; // class DinoXmlParser
456 /** Output operator for DinoXmlParser. */
457 ostream
&operator<<(ostream
&os
, const DinoXmlParser
&parser
);
459 } // end namespace ogdf