Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-08-06 09:24:28

0001 // -*- C++ -*-
0002 //
0003 // Element.hpp is a part of myXML
0004 // Copyright (C) 2012-2019 Simon Platzer, The Herwig Collaboration
0005 //
0006 // myXML is licenced under version 3 of the GPL, see COPYING for details.
0007 //
0008 
0009 #ifndef MYXML_Element_hpp_included
0010 #define MYXML_Element_hpp_included
0011 
0012 #include <string>
0013 #include <map>
0014 #include <list>
0015 #include <sstream>
0016 #include <iomanip>
0017 
0018 namespace XML {
0019 
0020   /**
0021    * \brief ElementTypes contains the element type enumeration
0022    * \author Simon Platzer
0023    */
0024   namespace ElementTypes {
0025 
0026     /**
0027      * The element type enumeration
0028      */
0029     enum EnumerateElementTypes {
0030 
0031       Unknown = -1,
0032       /** Unknown element type */
0033       Root = 0,
0034       /** The entire document */
0035       EmptyElement = 1,
0036       /** An empty element */
0037       Element = 2,
0038       /** An element */
0039       ProcessingInstruction = 3,
0040       /** A processing instruction */
0041       CharacterData = 4,
0042       /** Character data */
0043       ParsedCharacterData = 5,
0044       /** Parsed character data */
0045       Comment = 6
0046       /** A comment */
0047 
0048     };
0049 
0050   }
0051 
0052   /**
0053    * \brief Element represents a (tree of) XML elements
0054    * \author Simon Platzer
0055    */
0056   class Element {
0057 
0058   public:
0059 
0060     /**
0061      * The default constructor
0062      */
0063     Element()
0064       : theType(ElementTypes::Unknown) {}
0065 
0066     /**
0067      * The standard constructor
0068      */
0069     explicit Element(int newType,
0070              const std::string& newNameOrContent = "")
0071       : theType(newType), theNameOrContent(newNameOrContent) {}
0072 
0073 
0074     /**
0075      * The copy constructor
0076      */
0077     Element(const Element& other);
0078 
0079     /**
0080      * Assignment
0081      */
0082     Element& operator=(const Element& other);
0083   
0084     /** 
0085      * Comparison operator
0086      *
0087      */
0088     friend bool operator==(const XML::Element &one, const XML::Element &two);
0089     friend bool operator!=(const XML::Element &one, const XML::Element &two);
0090 
0091     /**
0092      * Combine operator
0093      * 
0094      * Operator checks if type and name is equal otherwises throws exception
0095      */
0096     friend XML::Element operator+(const XML::Element& one, const XML::Element& two);
0097     
0098   public:
0099 
0100     /**
0101      * Return the type of this element
0102      */
0103     int type() const { return theType; }
0104 
0105     /**
0106      * Return the name of this element
0107      */
0108     const std::string& name() const;
0109 
0110   public:
0111 
0112     /**
0113      * Return the content of this element
0114      */
0115     const std::string& content() const;
0116 
0117     /**
0118      * Access the content of this element
0119      */
0120     std::string& content();
0121 
0122     /**
0123      * Append to the content of this element
0124      */
0125     template<class T>
0126     Element& operator<<(const T& t) {
0127       assertContent();
0128       std::ostringstream out;
0129       out << std::setprecision(16) << t;
0130       theNameOrContent += out.str();
0131       return *this;
0132     }
0133 
0134   public:
0135 
0136     /**
0137      * Return true, if this element has attributes
0138      */
0139     bool hasAttributes() const {
0140       return 
0141     type() == ElementTypes::Element ||
0142     type() == ElementTypes::EmptyElement;
0143     }
0144 
0145     /**
0146      * Return true, if this element contains an attribute of the given name
0147      */
0148     bool hasAttribute(const std::string&) const;
0149 
0150     /**
0151      * Return the attributes
0152      */
0153     const std::map<std::string,std::string>& attributes() const;
0154 
0155     /**
0156      * Return the attribute of the given name
0157      */
0158     const std::string& attribute(const std::string&) const;
0159 
0160     /**
0161      * Access the attribute of the given name
0162      */
0163     std::string& attribute(const std::string&);
0164 
0165     /**
0166      * Represent an attribute
0167      */
0168     struct Attribute {
0169 
0170       /**
0171        * The attribute name
0172        */
0173       std::string name;
0174 
0175       /**
0176        * The attribute value
0177        */
0178       std::string value;
0179 
0180       /**
0181        * Construct an attribute
0182        */
0183       template<class T>
0184       Attribute(const std::string& newName,
0185         const T& newValue)
0186     : name(newName) {
0187     std::ostringstream valueOut;
0188     valueOut << std::setprecision(16) << newValue;
0189     value = valueOut.str();
0190     
0191 
0192       
0193       }
0194     
0195     /**
0196       * Comparison operators for attributes
0197       */
0198     inline bool operator==(const Attribute& other) {
0199       return ( name == other.name &&
0200       value == other.value);
0201     }
0202     inline bool operator!=(const Attribute& other) {
0203       return !(*this == other);
0204     }
0205     };
0206 
0207     /**
0208      * Append an attribute to this element
0209      */
0210     Element& operator<<(const Attribute&);
0211 
0212     /**
0213      * Append an attribute to this element
0214      */
0215     template<class T>
0216     void appendAttribute(const std::string& name, const T& t) {
0217       *this << Attribute(name,t);
0218     }
0219 
0220     /**
0221      * Get a value from an attribute
0222      */
0223     template<class T>
0224     void getFromAttribute(const std::string& name, T& t) const {
0225       std::istringstream in(attribute(name));
0226       in >> std::setprecision(16) >> t;
0227     }
0228 
0229   public:
0230 
0231     /**
0232      * Return true, if this element has children
0233      */
0234     bool hasChildren() const {
0235       return 
0236     type() == ElementTypes::Root ||
0237     type() == ElementTypes::Element;
0238     }
0239 
0240     /**
0241      * Return the list of children elements
0242      */
0243     const std::list<Element>& children() const;
0244 
0245     /**
0246      * Access the list of children elements
0247      */
0248     std::list<Element>& children();
0249 
0250     /**
0251      * Append a child element to this element
0252      */
0253     Element& append(const Element&);
0254 
0255     /**
0256      * Prepend a child element to this element
0257      */
0258     Element& prepend(const Element&);
0259 
0260     /**
0261      * Append a child element to this element
0262      */
0263     Element& operator<<(const Element&);
0264 
0265     /**
0266      * Insert an element before the given position
0267      */
0268     void insert(std::list<Element>::iterator, const Element&);
0269 
0270     /**
0271      * Erase an element at the given position
0272      */
0273     void erase(std::list<Element>::iterator);
0274 
0275     /**
0276      * Find the first element of the given type and name
0277      */
0278     std::list<Element>::const_iterator 
0279     findFirst(int type, const std::string& name) const;
0280 
0281     /**
0282      * Find all elements of the given type and name
0283      */
0284     std::pair<std::multimap<std::pair<int,std::string>,std::list<Element>::iterator>::const_iterator,
0285           std::multimap<std::pair<int,std::string>,std::list<Element>::iterator>::const_iterator>
0286     findAll(int type, const std::string& name) const;
0287 
0288   private:
0289 
0290     /**
0291      * The type of this element
0292      */
0293     int theType;
0294 
0295     /**
0296      * The name or character content of the element
0297      */
0298     std::string theNameOrContent;
0299 
0300     /**
0301      * The attributes of this element
0302      */
0303     std::map<std::string,std::string> theAttributes;
0304 
0305     /**
0306      * The children elements of this element
0307      */
0308     std::list<Element> theChildren;
0309 
0310     /**
0311      * Index children elements by type and name
0312      */
0313     std::multimap<std::pair<int,std::string>,std::list<Element>::iterator> theIndex;
0314 
0315   private:
0316 
0317     /**
0318      * Index elements by type and name
0319      */
0320     void index();
0321 
0322     /**
0323      * Assert that this element got a character content
0324      */ 
0325     void assertContent() const;
0326 
0327     /**
0328      * Assert that this element is named
0329      */
0330     void assertNamed() const;
0331 
0332     /**
0333      * Assert that this element contains attributes
0334      */
0335     void assertAttributes() const;
0336 
0337     /**
0338      * Assert that this element contains children elements
0339      */
0340     void assertChildren() const;
0341 
0342   };
0343 
0344 }
0345 
0346 #endif // MYXML_Element_hpp_included