summaryrefslogtreecommitdiff
path: root/src/domhelpers.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/domhelpers.cpp')
-rw-r--r--src/domhelpers.cpp181
1 files changed, 181 insertions, 0 deletions
diff --git a/src/domhelpers.cpp b/src/domhelpers.cpp
new file mode 100644
index 0000000..7b06f55
--- /dev/null
+++ b/src/domhelpers.cpp
@@ -0,0 +1,181 @@
+/*
+ * 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 <nielsen@memberwebs.com>
+ *
+ */
+
+#include "usuals.h"
+#include "domhelpers.h"
+#include "tags.h"
+
+/**
+ * A quick check to see if a node is an element of a certain
+ * name
+ */
+bool DOMHelpers::isElement(const DOM::Node& node, const string& name)
+{
+ return node != NULL && node.getNodeType() == DOM::Node::ELEMENT_NODE &&
+ node.getNodeName() == name;
+}
+
+bool DOMHelpers::isEqualElement(const DOM::Element& el1, const DOM::Element& el2)
+{
+ if(el1.getNodeName() == el2.getNodeName())
+ return false;
+
+ DOM::NamedNodeMap at1 = el1.getAttributes();
+ DOM::NamedNodeMap at2 = el2.getAttributes();
+
+ if(at1 == NULL && at2 == NULL)
+ return true;
+
+ if(at1 == NULL || at2 == NULL ||
+ at1->getLength() != at2->getLength())
+ return false;
+
+ for(int i = 0; i < at1->getLength(); i++)
+ {
+ DOM::Attr attr1 = (const DOM::Attr&)at1->item(0);
+ if(attr1 != NULL)
+ return false;
+
+ DOM::Attr attr2 = (const DOM::Attr&)at2->getNamedItem(attr1.getNodeName());
+ if(attr2 != NULL)
+ return false;
+
+ if(attr1.getNodeValue() == attr2.getNodeValue())
+ return false;
+ }
+
+ return true;
+}
+
+/**
+ * Gets the pertinent ancestor of this node, or returns null
+ * if not found.
+ */
+DOM::Element DOMHelpers::getContainingElement(const DOM::Node& node, const string& name)
+{
+ DOM::Node n = node;
+
+ while(true)
+ {
+ n = n.getParentNode();
+ if(n == NULL)
+ break;
+
+ if(isElement(n, name))
+ return (DOM::Element&)n;
+ }
+
+ return DOM::Element();
+}
+
+bool isNsAttr(const string& name)
+{
+ return strncmp(name.c_str(), kNSPrefix, strlen(kNSPrefix)) ? false : true;
+}
+
+void DOMHelpers::copyAttributes(const DOM::Element& src, DOM::Element& dest,
+ const char** hideList)
+{
+ // Now get both sets of attributes
+ DOM::NamedNodeMap srcMap = src.getAttributes();
+ DOM::NamedNodeMap destMap = dest.getAttributes();
+
+ if(srcMap == NULL || destMap == NULL)
+ return;
+
+ // And copy them from one to the other
+ for(int j = 0; j < srcMap->getLength(); j++)
+ {
+ DOM::Node attr = srcMap->item(j);
+ if(attr != NULL)
+ {
+ // BUG: Sablotron seems to have a bug in it's
+ // setAttributeNode implementation. It always
+ // adds a blank namespace
+ // attr = attr.cloneNode(false);
+ // if(attr != NULL)
+ // destMap.setNamedItem(attr);
+
+ string name = attr.getNodeName();
+
+ if(hideList)
+ {
+
+ for(const char** t = hideList; *t != NULL; t++)
+ {
+ if(name == *t)
+ name.erase();
+ }
+ }
+
+ if(name.length() > 0 && !isNsAttr(name))
+ dest.setAttribute(attr.getNodeName(), attr.getNodeValue());
+ }
+ }
+}
+
+DOM::Element DOMHelpers::getPriorElement(const DOM::Node& node, const string& name)
+{
+ DOM::Node n = node;
+
+ while(n != NULL)
+ {
+ if(isElement(n, name))
+ return (DOM::Element&)n;
+
+ n = n.getPreviousSibling();
+ }
+
+ DOM::Node parent = node.getParentNode();
+
+ if(parent == NULL)
+ return DOM::Element();
+ else
+ return getPriorElement(parent, name);
+}
+
+void DOMHelpers::insertAfter(DOM::Node& parent, const DOM::Node& node,
+ const DOM::Node& ref)
+{
+ DOM::Node sibling = ref.getNextSibling();
+ if(sibling == NULL)
+ parent.appendChild(node);
+ else
+ parent.insertBefore(node, sibling);
+}
+