/* * Copyright (c) 2004, Nate Nielsen * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the * following disclaimer. * * Redistributions in binary form must reproduce the * above copyright notice, this list of conditions and * the following disclaimer in the documentation and/or * other materials provided with the distribution. * * The names of contributors to this software may not be * used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * DAMAGE. * * * CONTRIBUTORS * Nate Nielsen * */ #ifndef __DOMHELPERS_H__ #define __DOMHELPERS_H__ #include "sablo.h" #include #include #include /* * DOMHelpers * * A collection of functions for doing some things with an XML DOM. * Used mainly by XMLComposer. */ class DOMHelpers { public: // Check if given node is an element with a certain name static bool isElement(const DOM::Node& node, const string& name); // Check if two elements have the same name and attributes static bool isEqualElement(const DOM::Element& el1, const DOM::Element& el2); // Copy attributes from one element to another optionaly ignoring some static void copyAttributes(const DOM::Element& src, DOM::Element& dest, const char** hideList); // Insert a child node after a given reference node static void insertAfter(DOM::Node& parent, const DOM::Node& node, const DOM::Node& ref); // Get containing element of a given name static DOM::Element getContainingElement(const DOM::Node& node, const string& name); // Get previous element (in XML flow) of a given name static DOM::Element getPriorElement(const DOM::Node& node, const string& name); // Get first child element of a given name static DOM::Element getChildElement(const DOM::Node& parent, const string& name); // Check if a given element is anothers ancestor static bool hasAncestor(const DOM::Node& ancestor, const DOM::Node& node); }; /* * ElementTable * * A table of elements matched to their ids for quick access while applying * things like fonts, styles, lists from their definitions. */ class ElementTable : public std::map { public: void load(const DOM::Node& parent, const string& name); DOM::Element get(const wstring& id) const; bool has(const wstring& id) const { return find(id) != end(); } void removeIds(); }; // Some other handy types typedef std::set StringSet; typedef std::stack NodeStack; /* * ElementIterator * * For iterating through the elements in a document. */ class ElementIterator : public std::iterator { public: ElementIterator() { m_flags = AFTER_LAST; } ElementIterator(const DOM::Element& top) { m_top = top; m_flags = BEFORE_FIRST; next(); } ElementIterator(const ElementIterator& x) { m_top = x.m_top; m_current = x.m_current; m_flags = x.m_flags; } const DOM::Element& operator*() const { return m_current; } const DOM::Element* operator->() const { return (&**this); } const ElementIterator& operator++() { next(); return (*this); } const ElementIterator& operator--() { prev(); return (*this); } // Friend comparision functions friend bool operator==(const ElementIterator& x, const ElementIterator& y); friend bool operator!=(const ElementIterator& x, const ElementIterator& y); // Implementation protected: void next(); DOM::Element nextel(DOM::Node node); void prev(); DOM::Element prevel(DOM::Node node); // Data protected: enum { ITERATING, BEFORE_FIRST, AFTER_LAST }; DOM::Element m_top; DOM::Element m_current; int m_flags; }; // friend functions inline bool operator==(const ElementIterator& x, const ElementIterator& y) { return y.m_current == x.m_current && y.m_flags == x.m_flags; } inline bool operator!=(const ElementIterator& x, const ElementIterator& y) { return (!(x == y)); } #endif // __DOMHELPERS_H__