diff --git a/src/pugixml.cpp b/src/pugixml.cpp index bf5835f..590d07f 100644 --- a/src/pugixml.cpp +++ b/src/pugixml.cpp @@ -3480,26 +3480,23 @@ PUGI__NS_BEGIN } } - PUGI__FN void node_output_attributes(xml_buffered_writer &writer, xml_node_struct *node, const char_t *indent, size_t indent_length, unsigned int flags, unsigned int depth) + PUGI__FN void node_output_attributes(xml_buffered_writer& writer, xml_node_struct* node, const char_t* indent, size_t indent_length, unsigned int flags, unsigned int depth) { const char_t* default_name = PUGIXML_TEXT(":anonymous"); - bool eachAttributeOnNewLine = PUGI__NODETYPE(node) != node_declaration - && (flags & format_indent) - && (flags & format_each_attribute_on_new_line) - && (flags & format_raw) == 0; - for (xml_attribute_struct* a = node->first_attribute; a; a = a->next_attribute) { - if (eachAttributeOnNewLine) + if ((flags & (format_indent_attributes | format_raw)) == format_indent_attributes) { writer.write('\n'); + text_output_indent(writer, indent, indent_length, depth + 1); } else { writer.write(' '); } + writer.write_string(a->name ? a->name : default_name); writer.write('=', '"'); @@ -3510,7 +3507,7 @@ PUGI__NS_BEGIN } } - PUGI__FN bool node_output_start(xml_buffered_writer &writer, xml_node_struct *node, const char_t *indent, size_t indent_length, unsigned int flags, unsigned int depth) + PUGI__FN bool node_output_start(xml_buffered_writer& writer, xml_node_struct* node, const char_t* indent, size_t indent_length, unsigned int flags, unsigned int depth) { const char_t* default_name = PUGIXML_TEXT(":anonymous"); const char_t* name = node->name ? node->name : default_name; @@ -3524,11 +3521,13 @@ PUGI__NS_BEGIN if (!node->first_child) { writer.write(' ', '/', '>'); + return false; } else { writer.write('>'); + return true; } } @@ -3543,7 +3542,7 @@ PUGI__NS_BEGIN writer.write('>'); } - PUGI__FN void node_output_simple(xml_buffered_writer &writer, xml_node_struct *node, const char_t *indent, size_t indent_length, unsigned int flags, unsigned int depth) + PUGI__FN void node_output_simple(xml_buffered_writer& writer, xml_node_struct* node, unsigned int flags) { const char_t* default_name = PUGIXML_TEXT(":anonymous"); @@ -3577,7 +3576,7 @@ PUGI__NS_BEGIN case node_declaration: writer.write('<', '?'); writer.write_string(node->name ? node->name : default_name); - node_output_attributes(writer, node, indent, indent_length, flags, depth); + node_output_attributes(writer, node, PUGIXML_TEXT(""), 0, flags | format_raw, 0); writer.write('?', '>'); break; @@ -3607,7 +3606,7 @@ PUGI__NS_BEGIN PUGI__FN void node_output(xml_buffered_writer& writer, xml_node_struct* root, const char_t* indent, unsigned int flags, unsigned int depth) { - size_t indent_length = ((flags & (format_indent | format_raw)) == format_indent) ? strlength(indent) : 0; + size_t indent_length = ((flags & (format_indent | format_indent_attributes)) && (flags & format_raw) == 0) ? strlength(indent) : 0; unsigned int indent_flags = indent_indent; xml_node_struct* node = root; @@ -3619,7 +3618,7 @@ PUGI__NS_BEGIN // begin writing current node if (PUGI__NODETYPE(node) == node_pcdata || PUGI__NODETYPE(node) == node_cdata) { - node_output_simple(writer, node, indent, indent_length, flags, depth); + node_output_simple(writer, node, flags); indent_flags = 0; } @@ -3654,7 +3653,7 @@ PUGI__NS_BEGIN } else { - node_output_simple(writer, node, indent, indent_length, flags, depth); + node_output_simple(writer, node, flags); indent_flags = indent_newline | indent_indent; } diff --git a/src/pugixml.hpp b/src/pugixml.hpp index 36ed955..02ca86b 100644 --- a/src/pugixml.hpp +++ b/src/pugixml.hpp @@ -203,13 +203,13 @@ namespace pugi // Open file using text mode in xml_document::save_file. This enables special character (i.e. new-line) conversions on some systems. This flag is off by default. const unsigned int format_save_file_text = 0x20; - // Set each attribute to new line - const unsigned int format_each_attribute_on_new_line = 0x40; + // Write every attribute on a new line with appropriate indentation. This flag is off by default. + const unsigned int format_indent_attributes = 0x40; + // 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; - const unsigned int format_indent_attributes = format_indent | format_each_attribute_on_new_line; - + // Forward declarations struct xml_attribute_struct; struct xml_node_struct; diff --git a/tests/test_write.cpp b/tests/test_write.cpp index d280840..df7b0b1 100644 --- a/tests/test_write.cpp +++ b/tests/test_write.cpp @@ -21,21 +21,31 @@ TEST_XML(write_indent, "text") CHECK_NODE_EX(doc, STR("\n\t\n\t\ttext\n\t\n\n"), STR("\t"), format_indent); } -TEST_XML(write_indent_attribute, "text") +TEST_XML(write_indent_attributes, "text") { CHECK_NODE_EX(doc, STR("\n\t\n\t\ttext\n\t\n\n"), STR("\t"), format_indent_attributes); } -TEST_XML(write_indent_attribute_empty_tag, "") +TEST_XML(write_indent_attributes_empty_element, "") { CHECK_NODE_EX(doc, STR("\n"), STR("\t"), format_indent_attributes); } -TEST_XML_FLAGS(write_indent_attribute_on_declaration, "", pugi::parse_full) +TEST_XML_FLAGS(write_indent_attributes_declaration, "", parse_full) { CHECK_NODE_EX(doc, STR("\n\n"), STR("\t"), format_indent_attributes); } +TEST_XML(write_indent_attributes_raw, "text") +{ + CHECK_NODE_EX(doc, STR("text"), STR("\t"), format_indent_attributes | format_raw); +} + +TEST_XML(write_indent_attributes_empty_indent, "text") +{ + CHECK_NODE_EX(doc, STR("\n\ntext\n\n\n"), STR(""), format_indent_attributes); +} + TEST_XML(write_pcdata, "text") { CHECK_NODE_EX(doc, STR("\n\t\n\t\ttext\n\n"), STR("\t"), format_indent);