diff options
-rw-r--r-- | src/pugixml.cpp | 20 | ||||
-rw-r--r-- | src/pugixml.hpp | 3 | ||||
-rw-r--r-- | tests/test_write.cpp | 8 |
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='㰀'/>") #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; |