summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/pugixml.cpp20
-rw-r--r--src/pugixml.hpp3
-rw-r--r--tests/test_write.cpp8
3 files changed, 25 insertions, 6 deletions
diff --git a/src/pugixml.cpp b/src/pugixml.cpp
index 7a6e946..3653e95 100644
--- a/src/pugixml.cpp
+++ b/src/pugixml.cpp
@@ -2856,6 +2856,14 @@ namespace
}
}
+ void text_output(xml_buffered_writer& writer, const char_t* s, chartypex_t type, unsigned int flags)
+ {
+ if (flags & format_no_escapes)
+ writer.write(s);
+ else
+ text_output_escaped(writer, s, type);
+ }
+
void text_output_cdata(xml_buffered_writer& writer, const char_t* s)
{
do
@@ -2878,7 +2886,7 @@ namespace
while (*s);
}
- void node_output_attributes(xml_buffered_writer& writer, const xml_node& node)
+ void node_output_attributes(xml_buffered_writer& writer, const xml_node& node, unsigned int flags)
{
const char_t* default_name = PUGIXML_TEXT(":anonymous");
@@ -2888,7 +2896,7 @@ namespace
writer.write(a.name()[0] ? a.name() : default_name);
writer.write('=', '"');
- text_output_escaped(writer, a.value(), ctx_special_attr);
+ text_output(writer, a.value(), ctx_special_attr, flags);
writer.write('"');
}
@@ -2917,7 +2925,7 @@ namespace
writer.write('<');
writer.write(name);
- node_output_attributes(writer, node);
+ node_output_attributes(writer, node, flags);
if (flags & format_raw)
{
@@ -2942,7 +2950,7 @@ namespace
writer.write('>');
if (node.first_child().type() == node_pcdata)
- text_output_escaped(writer, node.first_child().value(), ctx_special_pcdata);
+ text_output(writer, node.first_child().value(), ctx_special_pcdata, flags);
else
text_output_cdata(writer, node.first_child().value());
@@ -2969,7 +2977,7 @@ namespace
}
case node_pcdata:
- text_output_escaped(writer, node.value(), ctx_special_pcdata);
+ text_output(writer, node.value(), ctx_special_pcdata, flags);
if ((flags & format_raw) == 0) writer.write('\n');
break;
@@ -2992,7 +3000,7 @@ namespace
if (node.type() == node_declaration)
{
- node_output_attributes(writer, node);
+ node_output_attributes(writer, node, flags);
}
else if (node.value()[0])
{
diff --git a/src/pugixml.hpp b/src/pugixml.hpp
index 8fe34ec..1826b45 100644
--- a/src/pugixml.hpp
+++ b/src/pugixml.hpp
@@ -202,6 +202,9 @@ namespace pugi
// Omit default XML declaration even if there is no declaration in the document. This flag is off by default.
const unsigned int format_no_declaration = 0x08;
+ // Don't escape attribute values and PCDATA contents. This flag is off by default.
+ const unsigned int format_no_escapes = 0x10;
+
// The default set of formatting flags.
// Nodes are indented depending on their depth in DOM tree, a default declaration is output if document has none.
const unsigned int format_default = format_indent;
diff --git a/tests/test_write.cpp b/tests/test_write.cpp
index 3871bf6..094bf59 100644
--- a/tests/test_write.cpp
+++ b/tests/test_write.cpp
@@ -97,6 +97,14 @@ TEST_XML(write_escape_unicode, "<node attr='&#x3c00;'/>")
#endif
}
+TEST_XML(write_no_escapes, "<node attr=''>text</node>")
+{
+ doc.child(STR("node")).attribute(STR("attr")) = STR("<>'\"&\x04\r\n\t");
+ doc.child(STR("node")).first_child().set_value(STR("<>'\"&\x04\r\n\t"));
+
+ CHECK_NODE_EX(doc, STR("<node attr=\"<>'\"&\x04\r\n\t\"><>'\"&\x04\r\n\t</node>"), STR(""), format_raw | format_no_escapes);
+}
+
struct test_writer: xml_writer
{
std::basic_string<pugi::char_t> contents;