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.