summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorarseny.kapoulkine <arseny.kapoulkine@99668b35-9821-0410-8761-19e4c4f06640>2009-01-06 12:20:22 +0000
committerarseny.kapoulkine <arseny.kapoulkine@99668b35-9821-0410-8761-19e4c4f06640>2009-01-06 12:20:22 +0000
commit5054325378a67e1480fe2474836f6f5a919dc4bc (patch)
tree3dd559e9af1219ad2e8e9e4eb0bae24aff54494a /src
parentc507d9b10eaa3cd0d3065f4da8e0beb15a21d033 (diff)
Added node_declaration node type for <?xml nodes, added corresponding parse_declaration and format_no_declaration flags and parsing/saving/DOM functionality
git-svn-id: http://pugixml.googlecode.com/svn/trunk@104 99668b35-9821-0410-8761-19e4c4f06640
Diffstat (limited to 'src')
-rw-r--r--src/pugixml.cpp88
-rw-r--r--src/pugixml.hpp24
2 files changed, 96 insertions, 16 deletions
diff --git a/src/pugixml.cpp b/src/pugixml.cpp
index 5852814..99a13c2 100644
--- a/src/pugixml.cpp
+++ b/src/pugixml.cpp
@@ -859,7 +859,7 @@ namespace
if (!is_chartype(*s, ct_start_symbol)) // bad PI
return false;
- else if (OPTSET(parse_pi))
+ else if (OPTSET(parse_pi) || OPTSET(parse_declaration))
{
mark = s;
SCANWHILE(is_chartype(*s, ct_symbol)); // Read PI target
@@ -880,8 +880,16 @@ namespace
if ((mark[0] == 'x' || mark[0] == 'X') && (mark[1] == 'm' || mark[1] == 'M')
&& (mark[2] == 'l' || mark[2] == 'L') && mark[3] == 0)
{
+ if (OPTSET(parse_declaration))
+ {
+ PUSHNODE(node_declaration);
+
+ cursor->name = mark;
+
+ POPNODE();
+ }
}
- else
+ else if (OPTSET(parse_pi))
{
PUSHNODE(node_pi); // Append a new node on the tree.
@@ -894,15 +902,35 @@ namespace
else if ((mark[0] == 'x' || mark[0] == 'X') && (mark[1] == 'm' || mark[1] == 'M')
&& (mark[2] == 'l' || mark[2] == 'L') && mark[3] == 0)
{
- SCANFOR(*s == '?' && *(s+1) == '>'); // Look for '?>'.
- CHECK_ERROR();
- s += 2;
+ if (OPTSET(parse_declaration))
+ {
+ PUSHNODE(node_declaration);
+
+ cursor->name = mark;
+
+ // scan for tag end
+ mark = s;
+
+ SCANFOR(*s == '?' && *(s+1) == '>'); // Look for '?>'.
+ CHECK_ERROR();
+
+ // replace ending ? with / to terminate properly
+ *s = '/';
+
+ // parse attributes
+ s = mark;
+
+ goto LOC_ATTRIBUTES;
+ }
}
else
{
- PUSHNODE(node_pi); // Append a new node on the tree.
+ if (OPTSET(parse_pi))
+ {
+ PUSHNODE(node_pi); // Append a new node on the tree.
- cursor->name = mark;
+ cursor->name = mark;
+ }
if (is_chartype(ch, ct_space))
{
@@ -921,9 +949,12 @@ namespace
++s; // Step over >
- cursor->value = mark;
+ if (OPTSET(parse_pi))
+ {
+ cursor->value = mark;
- POPNODE();
+ POPNODE();
+ }
}
}
else // not parsing PI
@@ -1087,6 +1118,7 @@ namespace
}
else if (is_chartype(ch, ct_space))
{
+ LOC_ATTRIBUTES:
while (*s)
{
SKIPWS(); // Eat any whitespace.
@@ -1537,6 +1569,28 @@ namespace
if ((flags & format_raw) == 0) writer.write('\n');
break;
+ case node_declaration:
+ {
+ writer.write("<?");
+ writer.write(node.name());
+
+ for (xml_attribute a = node.first_attribute(); a; a = a.next_attribute())
+ {
+ writer.write(' ');
+ writer.write(a.name());
+ writer.write('=');
+ writer.write('"');
+
+ text_output_escaped(writer, a.value(), opt1_to_type<1>());
+
+ writer.write('"');
+ }
+
+ writer.write("?>");
+ if ((flags & format_raw) == 0) writer.write('\n');
+ break;
+ }
+
default:
;
}
@@ -2063,6 +2117,7 @@ namespace pugi
switch (type())
{
case node_pi:
+ case node_declaration:
case node_element:
{
bool insitu = _root->name_insitu;
@@ -2100,7 +2155,7 @@ namespace pugi
xml_attribute xml_node::append_attribute(const char* name)
{
- if (type() != node_element) return xml_attribute();
+ if (type() != node_element && type() != node_declaration) return xml_attribute();
xml_attribute a(_root->append_attribute(get_allocator()));
a.set_name(name);
@@ -2110,7 +2165,7 @@ namespace pugi
xml_attribute xml_node::insert_attribute_before(const char* name, const xml_attribute& attr)
{
- if (type() != node_element || attr.empty()) return xml_attribute();
+ if ((type() != node_element && type() != node_declaration) || attr.empty()) return xml_attribute();
// check that attribute belongs to *this
xml_attribute_struct* cur = attr._attr;
@@ -2136,7 +2191,7 @@ namespace pugi
xml_attribute xml_node::insert_attribute_after(const char* name, const xml_attribute& attr)
{
- if (type() != node_element || attr.empty()) return xml_attribute();
+ if ((type() != node_element && type() != node_declaration) || attr.empty()) return xml_attribute();
// check that attribute belongs to *this
xml_attribute_struct* cur = attr._attr;
@@ -2738,9 +2793,12 @@ namespace pugi
buffered_writer.write(utf8_bom, 3);
}
- buffered_writer.write("<?xml version=\"1.0\"?>");
- if (!(flags & format_raw)) buffered_writer.write("\n");
-
+ if (!(flags & format_no_declaration))
+ {
+ buffered_writer.write("<?xml version=\"1.0\"?>");
+ if (!(flags & format_raw)) buffered_writer.write("\n");
+ }
+
node_output(buffered_writer, *this, indent, flags, 0);
}
diff --git a/src/pugixml.hpp b/src/pugixml.hpp
index 26e2f0f..b1096fe 100644
--- a/src/pugixml.hpp
+++ b/src/pugixml.hpp
@@ -42,7 +42,8 @@ namespace pugi
node_pcdata, ///< E.g. '>...<'
node_cdata, ///< E.g. '<![CDATA[...]]>'
node_comment, ///< E.g. '<!--...-->'
- node_pi ///< E.g. '<?...?>'
+ node_pi, ///< E.g. '<?...?>'
+ node_declaration ///< E.g. '<?xml ...?>'
};
// Parsing options
@@ -155,6 +156,18 @@ namespace pugi
const unsigned int parse_wconv_attribute = 0x0080;
/**
+ * This flag determines if XML document declaration (this node has the form of <?xml ... ?> in XML)
+ * are to be put in DOM tree. If this flag is off, it is not put in the tree, but is still parsed
+ * and checked for correctness.
+ *
+ * The corresponding node in DOM tree will have type node_declaration, name "xml" and attributes,
+ * if any.
+ *
+ * This flag is off by default.
+ */
+ const unsigned int parse_declaration = 0x0100;
+
+ /**
* This is the default set of flags. It includes parsing CDATA sections (comments/PIs are not
* parsed), performing character and entity reference expansion, replacing whitespace characters
* with spaces in attribute values and performing EOL handling. Note, that PCDATA sections
@@ -188,6 +201,15 @@ namespace pugi
const unsigned int format_raw = 0x04;
/**
+ * If this flag is on, no default XML declaration is written to output file.
+ * This means that there will be no XML declaration in output stream unless there was one in XML document
+ * (i.e. if it was parsed with parse_declaration flag).
+ *
+ * This flag is off by default.
+ */
+ const unsigned int format_no_declaration = 0x08;
+
+ /**
* This is the default set of formatting flags. It includes indenting nodes depending on their
* depth in DOM tree.
*/