summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2014-10-10 21:38:50 +0100
committerCarl Hetherington <cth@carlh.net>2014-10-10 21:38:50 +0100
commit5800b1958cfb055fe1fb30461cbf73fb50e59e12 (patch)
tree338ed834582006126600866bfd0a775107b1f7e6
parented60523d354af3b18150da1e183e80dc52ee851a (diff)
Sort out xmlns stuff.
-rw-r--r--src/cxml.cc33
-rw-r--r--src/cxml.h16
-rw-r--r--test/ref/c.xml4
-rw-r--r--test/tests.cc13
4 files changed, 60 insertions, 6 deletions
diff --git a/src/cxml.cc b/src/cxml.cc
index 3285fe6..8bfb923 100644
--- a/src/cxml.cc
+++ b/src/cxml.cc
@@ -79,7 +79,11 @@ cxml::Node::write (xmlpp::Node* parent) const
node->add_child_text (_content);
}
- for (list<pair<string, string> >::const_iterator i = _attributes.begin(); i != _attributes.end(); ++i) {
+ for (KeyValueList::const_iterator i = _namespace_declarations.begin(); i != _namespace_declarations.end(); ++i) {
+ node->set_namespace_declaration (i->first, i->second);
+ }
+
+ for (KeyValueList::const_iterator i = _attributes.begin(); i != _attributes.end(); ++i) {
node->set_attribute (i->first, i->second);
}
@@ -183,7 +187,7 @@ cxml::Node::ignore_child (string name) const
string
cxml::Node::string_attribute (string name) const
{
- list<pair<string, string> >::const_iterator i = _attributes.begin ();
+ KeyValueList::const_iterator i = _attributes.begin ();
while (i != _attributes.end() && i->first != name) {
++i;
}
@@ -198,7 +202,7 @@ cxml::Node::string_attribute (string name) const
optional<string>
cxml::Node::optional_string_attribute (string name) const
{
- list<pair<string, string> >::const_iterator i;
+ KeyValueList::const_iterator i;
while (i != _attributes.end() && i->first != name) {
++i;
}
@@ -253,7 +257,7 @@ cxml::Node::namespace_prefix () const
void
cxml::Node::set_attribute (string name, string value)
{
- list<pair<string, string> >::iterator i = _attributes.begin ();
+ KeyValueList::iterator i = _attributes.begin ();
while (i != _attributes.end() && i->first != name) {
++i;
}
@@ -265,6 +269,21 @@ cxml::Node::set_attribute (string name, string value)
_attributes.push_back (make_pair (name, value));
}
+void
+cxml::Node::set_namespace_declaration (string uri, string ns)
+{
+ KeyValueList::iterator i = _namespace_declarations.begin ();
+ while (i != _namespace_declarations.end() && i->second != ns) {
+ ++i;
+ }
+
+ if (i != _namespace_declarations.end ()) {
+ _namespace_declarations.erase (i);
+ }
+
+ _namespace_declarations.push_back (make_pair (uri, ns));
+}
+
cxml::NodePtr
cxml::read_file (boost::filesystem::path file)
{
@@ -304,6 +323,12 @@ static void
write_to_xmlpp_document (cxml::ConstNodePtr node, xmlpp::Document& doc)
{
xmlpp::Element* root = doc.create_root_node (node->name ());
+
+ cxml::KeyValueList namespace_declarations = node->namespace_declarations ();
+ for (cxml::KeyValueList::const_iterator i = namespace_declarations.begin(); i != namespace_declarations.end(); ++i) {
+ root->set_namespace_declaration (i->first, i->second);
+ }
+
cxml::NodeList children = node->children ();
for (cxml::NodeList::const_iterator i = children.begin(); i != children.end(); ++i) {
(*i)->write (root);
diff --git a/src/cxml.h b/src/cxml.h
index 1c98bbf..993a662 100644
--- a/src/cxml.h
+++ b/src/cxml.h
@@ -69,6 +69,7 @@ class Node;
typedef boost::shared_ptr<cxml::Node> NodePtr;
typedef std::list<NodePtr> NodeList;
typedef boost::shared_ptr<const cxml::Node> ConstNodePtr;
+typedef std::list<std::pair<std::string, std::string> > KeyValueList;
class Node
{
@@ -185,6 +186,7 @@ public:
NodeList children () const;
NodeList children (std::string) const;
+
/** Add a child node with a given name */
NodePtr add_child (std::string name, std::string namespace_prefix = "")
{
@@ -194,17 +196,26 @@ public:
_children.push_back (n);
return n;
}
-
+
+ void set_namespace_declaration (std::string uri, std::string prefix = "");
+
+ KeyValueList namespace_declarations () const {
+ return _namespace_declarations;
+ }
+
void set_content (std::string c) {
_content = c;
}
/** @return The content of this node */
std::string content () const;
+
void set_attribute (std::string name, std::string value);
+
void set_namespace_prefix (std::string p) {
_namespace_prefix = p;
}
+
/** @return namespace prefix of this node */
std::string namespace_prefix () const;
/** This will mark a child as to be ignored when calling done() */
@@ -237,7 +248,8 @@ private:
std::string _name;
std::string _content;
std::string _namespace_prefix;
- std::list<std::pair<std::string, std::string> > _attributes;
+ KeyValueList _attributes;
+ KeyValueList _namespace_declarations;
mutable std::list<std::string> _taken;
};
diff --git a/test/ref/c.xml b/test/ref/c.xml
new file mode 100644
index 0000000..2b8667e
--- /dev/null
+++ b/test/ref/c.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<A xmlns="http://my.namespace" xmlns:foo="http://my.other.namespace">
+ <B/>
+</A>
diff --git a/test/tests.cc b/test/tests.cc
index 8b32498..f0ca967 100644
--- a/test/tests.cc
+++ b/test/tests.cc
@@ -110,3 +110,16 @@ BOOST_AUTO_TEST_CASE (write_test)
int r = system ("diff -u test/ref/b.xml build/test/b.xml");
BOOST_CHECK_EQUAL (WEXITSTATUS (r), 0);
}
+
+BOOST_AUTO_TEST_CASE (write2_test)
+{
+ cxml::NodePtr document (new cxml::Node);
+ document->set_name ("A");
+ document->add_child ("B");
+ document->set_namespace_declaration ("http://my.namespace");
+ document->set_namespace_declaration ("http://my.other.namespace", "foo");
+ write_to_file_formatted (document, "build/test/c.xml");
+
+ int r = system ("diff -u test/ref/c.xml build/test/c.xml");
+ BOOST_CHECK_EQUAL (WEXITSTATUS (r), 0);
+}