Skip to content

Commit f82dfd2

Browse files
committed
Update creating DTD documentation. Fixes #168
1 parent f225071 commit f82dfd2

File tree

2 files changed

+89
-83
lines changed

2 files changed

+89
-83
lines changed

ext/libxml/ruby_xml_dtd.c

Lines changed: 85 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -124,112 +124,118 @@ static VALUE rxml_dtd_type(VALUE self)
124124

125125
/*
126126
* call-seq:
127-
* XML::Dtd.new("DTD string") -> dtd
128-
* XML::Dtd.new("public", "system") -> dtd
129-
* XML::Dtd.new("name", "public", "system", document) -> external subset dtd
130-
* XML::Dtd.new("name", "public", "system", document, false) -> internal subset dtd
131-
* XML::Dtd.new("name", "public", "system", document, true) -> internal subset dtd
127+
* XML::Dtd.new(dtd_string) -> dtd
128+
* XML::Dtd.new(external_id, system_id) -> dtd
129+
* XML::Dtd.new(external_id, system_id, name, document, internal) -> dtd
132130
*
133-
* Create a new Dtd from the specified public and system
134-
* identifiers.
131+
* Create a new Dtd from the specified public and system identifiers:
132+
*
133+
* * The first usage creates a DTD from a string and requires 1 parameter.
134+
* * The second usage loads and parses an external DTD and requires 2 parameters.
135+
* * The third usage creates a new internal or external DTD and requires 3 parameters and 2 optional parameters.
136+
* It then attaches the DTD to the specified document if it is not nil
137+
*
138+
* Parameters:
139+
*
140+
* dtd_string - A string that contains a complete DTD
141+
* external_id - A string that specifies the DTD's external name. For example, "-//W3C//DTD XHTML 1.0 Transitional//EN"
142+
* system_id - A string that specififies the DTD's system name. For example, "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
143+
* name - A string that specifies the DTD's name. For example "xhtml1".
144+
* document - A xml document.
145+
* internal - Boolean value indicating whether this is an internal or external DTD. Optional. If not specified
146+
* then external is assumed.
135147
*/
136148
static VALUE rxml_dtd_initialize(int argc, VALUE *argv, VALUE self)
137149
{
138-
VALUE external, system, dtd_string;
139-
xmlParserInputBufferPtr buffer;
140-
xmlCharEncoding enc = XML_CHAR_ENCODING_NONE;
141-
xmlChar *new_string;
142150
xmlDtdPtr xdtd;
151+
VALUE external, system;
143152

144-
// 1 argument -- string --> parsujeme jako dtd
145-
// 2 arguments -- public, system --> bude se hledat
146-
// 3 arguments -- public, system, name --> creates an external subset (any parameter may be nil)
147-
// 4 arguments -- public, system, name, doc --> creates an external subset (any parameter may be nil)
148-
// 5 arguments -- public, system, name, doc, true --> creates an internal subset (all but last parameter may be nil)
149153
switch (argc)
150154
{
151-
case 3:
152-
case 4:
153-
case 5: {
154-
VALUE name, doc, internal;
155-
const xmlChar *xname = NULL, *xpublic = NULL, *xsystem = NULL;
156-
xmlDocPtr xdoc = NULL;
155+
case 3:
156+
case 4:
157+
case 5:
158+
{
159+
const xmlChar *xname = NULL, *xpublic = NULL, *xsystem = NULL;
160+
xmlDocPtr xdoc = NULL;
157161

158-
rb_scan_args(argc, argv, "32", &external, &system, &name, &doc, &internal);
162+
VALUE name, doc, internal;
163+
rb_scan_args(argc, argv, "32", &external, &system, &name, &doc, &internal);
159164

160-
if (external != Qnil) {
161-
Check_Type(external, T_STRING);
162-
xpublic = (const xmlChar*) StringValuePtr(external);
163-
}
164-
if (system != Qnil) {
165-
Check_Type(system, T_STRING);
166-
xsystem = (const xmlChar*) StringValuePtr(system);
167-
}
168-
if (name != Qnil) {
169-
Check_Type(name, T_STRING);
170-
xname = (const xmlChar*) StringValuePtr(name);
171-
}
172-
if (doc != Qnil) {
173-
if (rb_obj_is_kind_of(doc, cXMLDocument) == Qfalse)
174-
rb_raise(rb_eTypeError, "Must pass an LibXML::XML::Document object");
175-
Data_Get_Struct(doc, xmlDoc, xdoc);
176-
}
165+
Check_Type(external, T_STRING);
166+
xpublic = (const xmlChar*) StringValuePtr(external);
177167

178-
if (internal == Qnil || internal == Qfalse)
179-
xdtd = xmlNewDtd(xdoc, xname, xpublic, xsystem);
180-
else
181-
xdtd = xmlCreateIntSubset(xdoc, xname, xpublic, xsystem);
168+
Check_Type(system, T_STRING);
169+
xsystem = (const xmlChar*) StringValuePtr(system);
182170

183-
if (xdtd == NULL)
184-
rxml_raise(xmlGetLastError());
171+
Check_Type(name, T_STRING);
172+
xname = (const xmlChar*) StringValuePtr(name);
185173

186-
/* Document will free this dtd now. */
187-
RDATA(self)->dfree = NULL;
188-
DATA_PTR(self) = xdtd;
174+
if (doc != Qnil)
175+
{
176+
if (rb_obj_is_kind_of(doc, cXMLDocument) == Qfalse)
177+
rb_raise(rb_eTypeError, "Must pass an LibXML::XML::Document object");
178+
Data_Get_Struct(doc, xmlDoc, xdoc);
179+
}
189180

190-
xmlSetTreeDoc((xmlNodePtr) xdtd, xdoc);
191-
}
192-
break;
181+
if (internal == Qnil || internal == Qfalse)
182+
xdtd = xmlNewDtd(xdoc, xname, xpublic, xsystem);
183+
else
184+
xdtd = xmlCreateIntSubset(xdoc, xname, xpublic, xsystem);
193185

194-
case 2:
195-
rb_scan_args(argc, argv, "20", &external, &system);
186+
if (xdtd == NULL)
187+
rxml_raise(xmlGetLastError());
196188

197-
Check_Type(external, T_STRING);
198-
Check_Type(system, T_STRING);
189+
/* The document will free the dtd so Ruby should not */
190+
RDATA(self)->dfree = NULL;
191+
DATA_PTR(self) = xdtd;
199192

200-
xdtd = xmlParseDTD((xmlChar*) StringValuePtr(external),
201-
(xmlChar*) StringValuePtr(system));
193+
xmlSetTreeDoc((xmlNodePtr) xdtd, xdoc);
194+
}
195+
break;
202196

203-
if (xdtd == NULL)
204-
rxml_raise(xmlGetLastError());
197+
case 2:
198+
{
199+
rb_scan_args(argc, argv, "20", &external, &system);
205200

206-
DATA_PTR(self) = xdtd;
201+
Check_Type(external, T_STRING);
202+
Check_Type(system, T_STRING);
207203

208-
xmlSetTreeDoc((xmlNodePtr) xdtd, NULL);
209-
break;
204+
xdtd = xmlParseDTD((xmlChar*) StringValuePtr(external), (xmlChar*) StringValuePtr(system));
210205

211-
case 1:
212-
rb_scan_args(argc, argv, "10", &dtd_string);
213-
Check_Type(dtd_string, T_STRING);
206+
if (xdtd == NULL)
207+
rxml_raise(xmlGetLastError());
214208

215-
/* Note that buffer is freed by xmlParserInputBufferPush*/
216-
buffer = xmlAllocParserInputBuffer(enc);
217-
new_string = xmlStrdup((xmlChar*) StringValuePtr(dtd_string));
218-
xmlParserInputBufferPush(buffer, xmlStrlen(new_string),
219-
(const char*) new_string);
209+
DATA_PTR(self) = xdtd;
220210

221-
xdtd = xmlIOParseDTD(NULL, buffer, enc);
211+
xmlSetTreeDoc((xmlNodePtr) xdtd, NULL);
212+
break;
213+
}
214+
case 1:
215+
{
216+
VALUE dtd_string;
217+
rb_scan_args(argc, argv, "10", &dtd_string);
218+
Check_Type(dtd_string, T_STRING);
222219

223-
if (xdtd == NULL)
224-
rxml_raise(xmlGetLastError());
220+
/* Note that buffer is freed by xmlParserInputBufferPush*/
221+
xmlCharEncoding enc = XML_CHAR_ENCODING_NONE;
222+
xmlParserInputBufferPtr buffer = xmlAllocParserInputBuffer(enc);
223+
xmlChar *new_string = xmlStrdup((xmlChar*) StringValuePtr(dtd_string));
224+
xmlParserInputBufferPush(buffer, xmlStrlen(new_string),
225+
(const char*) new_string);
225226

226-
xmlFree(new_string);
227+
xdtd = xmlIOParseDTD(NULL, buffer, enc);
227228

228-
DATA_PTR(self) = xdtd;
229-
break;
229+
if (xdtd == NULL)
230+
rxml_raise(xmlGetLastError());
230231

231-
default:
232-
rb_raise(rb_eArgError, "wrong number of arguments");
232+
xmlFree(new_string);
233+
234+
DATA_PTR(self) = xdtd;
235+
break;
236+
}
237+
default:
238+
rb_raise(rb_eArgError, "wrong number of arguments");
233239
}
234240

235241
return self;

test/test_dtd.rb

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,27 +31,27 @@ def dtd
3131
end
3232

3333
def test_internal_subset
34-
xhtml_dtd = LibXML::XML::Dtd.new "-//W3C//DTD XHTML 1.0 Transitional//EN", "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd", nil, nil, true
34+
xhtml_dtd = LibXML::XML::Dtd.new("-//W3C//DTD XHTML 1.0 Transitional//EN", "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd", nil, nil, true)
3535
assert xhtml_dtd.name.nil?
3636
assert_equal "-//W3C//DTD XHTML 1.0 Transitional//EN", xhtml_dtd.external_id
3737
assert_equal "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd", xhtml_dtd.uri
3838
assert_equal "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd", xhtml_dtd.system_id
3939

40-
xhtml_dtd = LibXML::XML::Dtd.new "-//W3C//DTD XHTML 1.0 Transitional//EN", "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd", "xhtml1", nil, true
40+
xhtml_dtd = LibXML::XML::Dtd.new("-//W3C//DTD XHTML 1.0 Transitional//EN", "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd", "xhtml1", nil, true)
4141
assert_equal "xhtml1", xhtml_dtd.name
4242
assert_equal "-//W3C//DTD XHTML 1.0 Transitional//EN", xhtml_dtd.external_id
4343
assert_equal "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd", xhtml_dtd.uri
4444
assert_equal "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd", xhtml_dtd.system_id
4545
end
4646

4747
def test_external_subset
48-
xhtml_dtd = LibXML::XML::Dtd.new "-//W3C//DTD XHTML 1.0 Transitional//EN", "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd", nil
48+
xhtml_dtd = LibXML::XML::Dtd.new("-//W3C//DTD XHTML 1.0 Transitional//EN", "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd", nil)
4949
assert xhtml_dtd.name.nil?
5050
assert_equal "-//W3C//DTD XHTML 1.0 Transitional//EN", xhtml_dtd.external_id
5151
assert_equal "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd", xhtml_dtd.uri
5252
assert_equal "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd", xhtml_dtd.system_id
5353

54-
xhtml_dtd = LibXML::XML::Dtd.new "-//W3C//DTD XHTML 1.0 Transitional//EN", "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd", "xhtml1"
54+
xhtml_dtd = LibXML::XML::Dtd.new("-//W3C//DTD XHTML 1.0 Transitional//EN", "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd", "xhtml1")
5555
assert_equal "xhtml1", xhtml_dtd.name
5656
assert_equal "-//W3C//DTD XHTML 1.0 Transitional//EN", xhtml_dtd.external_id
5757
assert_equal "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd", xhtml_dtd.uri

0 commit comments

Comments
 (0)