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
This commit is contained in:
parent
c507d9b10e
commit
5054325378
@ -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);
|
||||
}
|
||||
|
||||
|
||||
@ -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
|
||||
@ -154,6 +155,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
|
||||
@ -187,6 +200,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.
|
||||
|
||||
Loading…
Reference in New Issue
Block a user