class Ox::Builder
An XML builder.
Public Class Methods
Creates a new Builder that will write to a file.
-
filename
(String) filename to write to -
options
- (Hash) formating options-
:indent
(Fixnum) indentaion level -
:size
(Fixnum) the initial size of the string buffer
-
static VALUE builder_file(int argc, VALUE *argv, VALUE self) { Builder b = ALLOC(struct _Builder); int indent = ox_default_options.indent; long buf_size = 0; FILE *f; if (1 > argc) { rb_raise(ox_arg_error_class, "missing filename"); } Check_Type(*argv, T_STRING); if (NULL == (f = fopen(StringValuePtr(*argv), "w"))) { xfree(b); rb_raise(rb_eIOError, "%s\n", strerror(errno)); } if (2 == argc) { volatile VALUE v; rb_check_type(argv[1], T_HASH); if (Qnil != (v = rb_hash_lookup(argv[1], ox_indent_sym))) { if (rb_cFixnum != rb_obj_class(v)) { rb_raise(ox_parse_error_class, ":indent must be a fixnum.\n"); } indent = NUM2INT(v); } if (Qnil != (v = rb_hash_lookup(argv[1], ox_size_sym))) { if (rb_cFixnum != rb_obj_class(v)) { rb_raise(ox_parse_error_class, ":size must be a fixnum.\n"); } buf_size = NUM2LONG(v); } } b->file = f; init(b, fileno(f), indent, buf_size); if (rb_block_given_p()) { volatile VALUE rb = Data_Wrap_Struct(builder_class, NULL, builder_free, b); rb_yield(rb); bclose(b); return Qnil; } else { return Data_Wrap_Struct(builder_class, NULL, builder_free, b); } }
Creates a new Builder that will write to an IO instance.
-
io
(String) IO to write to -
options
- (Hash) formating options-
:indent
(Fixnum) indentaion level -
:size
(Fixnum) the initial size of the string buffer
-
static VALUE builder_io(int argc, VALUE *argv, VALUE self) { Builder b = ALLOC(struct _Builder); int indent = ox_default_options.indent; long buf_size = 0; int fd; volatile VALUE v; if (1 > argc) { rb_raise(ox_arg_error_class, "missing IO object"); } if (!rb_respond_to(*argv, ox_fileno_id) || Qnil == (v = rb_funcall(*argv, ox_fileno_id, 0)) || 0 == (fd = FIX2INT(v))) { rb_raise(rb_eIOError, "expected an IO that has a fileno."); } if (2 == argc) { volatile VALUE v; rb_check_type(argv[1], T_HASH); if (Qnil != (v = rb_hash_lookup(argv[1], ox_indent_sym))) { if (rb_cFixnum != rb_obj_class(v)) { rb_raise(ox_parse_error_class, ":indent must be a fixnum.\n"); } indent = NUM2INT(v); } if (Qnil != (v = rb_hash_lookup(argv[1], ox_size_sym))) { if (rb_cFixnum != rb_obj_class(v)) { rb_raise(ox_parse_error_class, ":size must be a fixnum.\n"); } buf_size = NUM2LONG(v); } } b->file = NULL; init(b, fd, indent, buf_size); if (rb_block_given_p()) { volatile VALUE rb = Data_Wrap_Struct(builder_class, NULL, builder_free, b); rb_yield(rb); bclose(b); return Qnil; } else { return Data_Wrap_Struct(builder_class, NULL, builder_free, b); } }
Creates a new Builder that will write to a string that can be retrieved with the #to_s() method. If a block is given it is executed with a single parameter which is the builder instance. The return value is then the generated string.
-
options
- (Hash) formating options-
:indent
(Fixnum) indentaion level -
:size
(Fixnum) the initial size of the string buffer
-
static VALUE builder_new(int argc, VALUE *argv, VALUE self) { Builder b = ALLOC(struct _Builder); int indent = ox_default_options.indent; long buf_size = 0; if (1 == argc) { volatile VALUE v; rb_check_type(*argv, T_HASH); if (Qnil != (v = rb_hash_lookup(*argv, ox_indent_sym))) { if (rb_cFixnum != rb_obj_class(v)) { rb_raise(ox_parse_error_class, ":indent must be a fixnum.\n"); } indent = NUM2INT(v); } if (Qnil != (v = rb_hash_lookup(*argv, ox_size_sym))) { if (rb_cFixnum != rb_obj_class(v)) { rb_raise(ox_parse_error_class, ":size must be a fixnum.\n"); } buf_size = NUM2LONG(v); } } b->file = NULL; init(b, 0, indent, buf_size); if (rb_block_given_p()) { volatile VALUE rb = Data_Wrap_Struct(builder_class, NULL, builder_free, b); rb_yield(rb); bclose(b); return to_s(b); } else { return Data_Wrap_Struct(builder_class, NULL, builder_free, b); } }
Public Instance Methods
Adds a CDATA element to the XML string being formed.
-
data
- (String) contents of the CDATA element
static VALUE builder_cdata(VALUE self, VALUE data) { Builder b = (Builder)DATA_PTR(self); volatile VALUE v = data; if (T_STRING != rb_type(v)) { v = rb_funcall(v, ox_to_s_id, 0); } i_am_a_child(b, false); append_indent(b); buf_append_string(&b->buf, "<![CDATA[", 9); buf_append_string(&b->buf, StringValuePtr(v), RSTRING_LEN(v)); buf_append_string(&b->buf, "]]>", 3); return Qnil; }
Closes the all elements and the document.
static VALUE builder_close(VALUE self) { bclose((Builder)DATA_PTR(self)); return Qnil; }
Adds a comment element to the XML string being formed.
-
text
- (String) contents of the comment
static VALUE builder_comment(VALUE self, VALUE text) { Builder b = (Builder)DATA_PTR(self); rb_check_type(text, T_STRING); i_am_a_child(b, false); append_indent(b); buf_append_string(&b->buf, "<!-- ", 5); buf_append_string(&b->buf, StringValuePtr(text), RSTRING_LEN(text)); buf_append_string(&b->buf, " --/> ", 5); return Qnil; }
Adds a DOCTYPE element to the XML string being formed.
-
text
- (String) contents of the doctype
static VALUE builder_doctype(VALUE self, VALUE text) { Builder b = (Builder)DATA_PTR(self); rb_check_type(text, T_STRING); i_am_a_child(b, false); append_indent(b); buf_append_string(&b->buf, "<!DOCTYPE ", 10); buf_append_string(&b->buf, StringValuePtr(text), RSTRING_LEN(text)); buf_append(&b->buf, '>'); return Qnil; }
Adds an element with the name and attributes provided. If a block is given then on closing of the block a pop() done at the close of the block.
-
name
- (String) name of the element -
attributes
- (Hash) of the element
static VALUE builder_element(int argc, VALUE *argv, VALUE self) { Builder b = (Builder)DATA_PTR(self); Element e; const char *name; int len; if (1 > argc) { rb_raise(ox_arg_error_class, "missing element name"); } i_am_a_child(b, false); append_indent(b); b->depth++; if (MAX_DEPTH <= b->depth) { rb_raise(ox_arg_error_class, "XML too deeply nested"); } switch (rb_type(*argv)) { case T_STRING: name = StringValuePtr(*argv); len = RSTRING_LEN(*argv); break; case T_SYMBOL: name = rb_id2name(SYM2ID(*argv)); len = strlen(name); break; default: rb_raise(ox_arg_error_class, "expected a Symbol or String for an element name"); break; } e = &b->stack[b->depth]; if (sizeof(e->buf) <= len) { e->name = strdup(name); *e->buf = '\0'; } else { strcpy(e->buf, name); e->name = e->buf; } e->len = len; e->has_child = false; e->non_text_child = false; buf_append(&b->buf, '<'); buf_append_string(&b->buf, e->name, len); if (1 < argc) { rb_hash_foreach(argv[1], append_attr, (VALUE)b); } // Do not close with > or /> yet. That is done with i_am_a_child() or pop(). if (rb_block_given_p()) { rb_yield(self); pop(b); } return Qnil; }
Adds the top level <?xml?> element.
-
decl
- (String) 'xml' expected -
options
- (Hash) version or encoding
static VALUE builder_instruct(int argc, VALUE *argv, VALUE self) { Builder b = (Builder)DATA_PTR(self); i_am_a_child(b, false); append_indent(b); if (0 == argc) { buf_append_string(&b->buf, "<?xml?>", 7); } else { volatile VALUE v; buf_append_string(&b->buf, "<?", 2); append_sym_str(&b->buf, *argv); if (1 < argc && rb_cHash == rb_obj_class(argv[1])) { if (Qnil != (v = rb_hash_lookup(argv[1], ox_version_sym))) { if (rb_cString != rb_obj_class(v)) { rb_raise(ox_parse_error_class, ":version must be a Symbol.\n"); } buf_append_string(&b->buf, " version=\"", 10); buf_append_string(&b->buf, StringValuePtr(v), RSTRING_LEN(v)); buf_append(&b->buf, '"'); } if (Qnil != (v = rb_hash_lookup(argv[1], ox_encoding_sym))) { if (rb_cString != rb_obj_class(v)) { rb_raise(ox_parse_error_class, ":encoding must be a Symbol.\n"); } buf_append_string(&b->buf, " encoding=\"", 11); buf_append_string(&b->buf, StringValuePtr(v), RSTRING_LEN(v)); buf_append(&b->buf, '"'); strncpy(b->encoding, StringValuePtr(v), sizeof(b->encoding)); b->encoding[sizeof(b->encoding) - 1] = '\0'; } if (Qnil != (v = rb_hash_lookup(argv[1], ox_standalone_sym))) { if (rb_cString != rb_obj_class(v)) { rb_raise(ox_parse_error_class, ":standalone must be a Symbol.\n"); } buf_append_string(&b->buf, " standalone=\"", 13); buf_append_string(&b->buf, StringValuePtr(v), RSTRING_LEN(v)); buf_append(&b->buf, '"'); } } buf_append_string(&b->buf, "?>", 2); } return Qnil; }
Closes the current element.
static VALUE builder_pop(VALUE self) { pop((Builder)DATA_PTR(self)); return Qnil; }
Adds the provided string directly to the XML without formatting or modifications.
-
text
- (String) contents to be added
static VALUE builder_raw(VALUE self, VALUE text) { Builder b = (Builder)DATA_PTR(self); volatile VALUE v = text; if (T_STRING != rb_type(v)) { v = rb_funcall(v, ox_to_s_id, 0); } i_am_a_child(b, true); buf_append_string(&b->buf, StringValuePtr(v), RSTRING_LEN(v)); return Qnil; }
Adds a text element to the XML string being formed.
-
text
- (String) contents of the text field
static VALUE builder_text(VALUE self, VALUE text) { Builder b = (Builder)DATA_PTR(self); volatile VALUE v = text; if (T_STRING != rb_type(v)) { v = rb_funcall(v, ox_to_s_id, 0); } i_am_a_child(b, true); append_string(&b->buf, StringValuePtr(v), RSTRING_LEN(v)); return Qnil; }
Returns the JSON document string in what ever state the construction is at.
static VALUE builder_to_s(VALUE self) { return to_s((Builder)DATA_PTR(self)); }