The quote character to use for the attribute value's delimiter.
The name of the attribute.
The value of the attribute.
Whether a newline followed by an indent will be written to the output range before the attribute. Note that unlike most write functions, the default is Newline.no (since it's more common to not want newlines between attributes).
XMLWritingException if the given name is not a valid XML attribute name, if the given value is not a valid XML attribute value, or if the given name has already been written to the current start tag. dxml.util.encodeAttr can be used to encode any characters that are not legal in their literal form in an attribute value but are legal as entity references.
1 import std.array : appender; 2 import std.exception : assertThrown; 3 import dxml.util : encodeAttr; 4 5 auto writer = xmlWriter(appender!string()); 6 7 writer.openStartTag("root", Newline.no); 8 assert(writer.output.data == "<root"); 9 10 writer.writeAttr("a", "one"); 11 assert(writer.output.data == `<root a="one"`); 12 13 writer.writeAttr("b", "two"); 14 assert(writer.output.data == `<root a="one" b="two"`); 15 16 // It's illegal for two attributes on the same start tag 17 // to have the same name. 18 assertThrown!XMLWritingException(writer.writeAttr("a", "three")); 19 20 // Invalid name. 21 assertThrown!XMLWritingException(writer.writeAttr("=", "value")); 22 23 // Can't have a quote that matches the enclosing quote. 24 assertThrown!XMLWritingException(writer.writeAttr("c", `foo"bar`)); 25 assertThrown!XMLWritingException(writer.writeAttr!'\''("c", "foo'bar")); 26 27 // Unchanged after an XMLWritingException is thrown. 28 assert(writer.output.data == `<root a="one" b="two"`); 29 30 writer.closeStartTag(); 31 assert(writer.output.data == `<root a="one" b="two">`); 32 33 writer.openStartTag("foobar"); 34 assert(writer.output.data == 35 `<root a="one" b="two">` ~ "\n" ~ 36 " <foobar"); 37 38 // " is the default for the quote character, but ' can be specified. 39 writer.writeAttr!'\''("answer", "42"); 40 assert(writer.output.data == 41 `<root a="one" b="two">` ~ "\n" ~ 42 " <foobar answer='42'"); 43 44 writer.writeAttr("base", "13", Newline.yes); 45 assert(writer.output.data == 46 `<root a="one" b="two">` ~ "\n" ~ 47 " <foobar answer='42'\n" ~ 48 ` base="13"`); 49 50 writer.closeStartTag(); 51 assert(writer.output.data == 52 `<root a="one" b="two">` ~ "\n" ~ 53 " <foobar answer='42'\n" ~ 54 ` base="13">`); 55 56 writer.openStartTag("tag"); 57 assert(writer.output.data == 58 `<root a="one" b="two">` ~ "\n" ~ 59 " <foobar answer='42'\n" ~ 60 ` base="13">` ~ "\n" ~ 61 " <tag"); 62 63 // &, <, and > are not legal in an attribute value. 64 assertThrown!XMLWritingException(writer.writeAttr("foo", "&")); 65 66 // Unchanged after an XMLWritingException is thrown. 67 assert(writer.output.data == 68 `<root a="one" b="two">` ~ "\n" ~ 69 " <foobar answer='42'\n" ~ 70 ` base="13">` ~ "\n" ~ 71 " <tag"); 72 73 // Use dxml.util.encodeAttr to encode characters that aren't 74 // legal in an attribute value but can legally be encoded. 75 writer.writeAttr("foo", encodeAttr("&")); 76 assert(writer.output.data == 77 `<root a="one" b="two">` ~ "\n" ~ 78 " <foobar answer='42'\n" ~ 79 ` base="13">` ~ "\n" ~ 80 ` <tag foo="&"`); 81 82 writer.closeStartTag(EmptyTag.yes); 83 assert(writer.output.data == 84 `<root a="one" b="two">` ~ "\n" ~ 85 " <foobar answer='42'\n" ~ 86 ` base="13">` ~ "\n" ~ 87 ` <tag foo="&"/>`); 88 89 writer.writeEndTag(); 90 writer.writeEndTag(); 91 assert(writer.output.data == 92 `<root a="one" b="two">` ~ "\n" ~ 93 " <foobar answer='42'\n" ~ 94 ` base="13">` ~ "\n" ~ 95 ` <tag foo="&"/>` ~ "\n" ~ 96 " </foobar>\n" ~ 97 "</root>");
Writes an attribute for a start tag to the output range.
It is an error to call writeAttr except between calls to openStartTag and closeStartTag.