mirror of
https://github.com/michaelrsweet/mxml.git
synced 2024-11-24 03:15:30 +00:00
SAX callback now returns a boolean (Issue #51)
This commit is contained in:
parent
5c66db0383
commit
3df751f37b
@ -5,6 +5,8 @@
|
||||
`MXML_TYPE_DIRECTIVE` node types (Issue #250)
|
||||
- Renamed `mxml_type_t` enumerations to `MXML_TYPE_xxx` (Issue #251)
|
||||
- Updated APIs to use bool type instead of an int representing a boolean value.
|
||||
- Updated the SAX callback to return a `bool` value to control processing
|
||||
(Issue #51)
|
||||
|
||||
|
||||
# Changes in Mini-XML 3.3.2
|
||||
|
@ -154,13 +154,13 @@ functions retrieve the value from a node:
|
||||
|
||||
mxml_node_t *node;
|
||||
|
||||
int intvalue = mxmlGetInteger(node);
|
||||
long intvalue = mxmlGetInteger(node);
|
||||
|
||||
const char *opaquevalue = mxmlGetOpaque(node);
|
||||
|
||||
double realvalue = mxmlGetReal(node);
|
||||
|
||||
int whitespacevalue;
|
||||
bool whitespacevalue;
|
||||
const char *textvalue = mxmlGetText(node, &whitespacevalue);
|
||||
.fi
|
||||
.PP
|
||||
|
24
doc/body.md
24
doc/body.md
@ -88,7 +88,7 @@ The Mini-XML library is included with your program using the `-lmxml` option:
|
||||
If you have the `pkg-config` software installed, you can use it to determine the
|
||||
proper compiler and linker options for your installation:
|
||||
|
||||
gcc `pkg-config --cflags mxml` -o myprogram myprogram.c `pkg-config --libs mxml`
|
||||
gcc `pkg-config --cflags mxml4` -o myprogram myprogram.c `pkg-config --libs mxml4`
|
||||
|
||||
|
||||
Loading an XML File
|
||||
@ -1172,14 +1172,18 @@ mxmlSAXLoadString(mxml_node_t *top, const char *s,
|
||||
|
||||
Each function works like the corresponding `mxmlLoad` function but uses a
|
||||
callback to process each node as it is read. The callback function receives the
|
||||
node, an event code, and a user data pointer you supply:
|
||||
node, an event code, and a user data pointer you supply and returns `true` to
|
||||
continue processing or `false` to stop:
|
||||
|
||||
```c
|
||||
void
|
||||
bool
|
||||
sax_cb(mxml_node_t *node, mxml_sax_event_t event,
|
||||
void *data)
|
||||
{
|
||||
... do something ...
|
||||
|
||||
// Continue processing...
|
||||
return (true);
|
||||
}
|
||||
```
|
||||
|
||||
@ -1187,8 +1191,7 @@ The event will be one of the following:
|
||||
|
||||
- `MXML_SAX_EVENT_CDATA`: CDATA was just read.
|
||||
- `MXML_SAX_EVENT_COMMENT`: A comment was just read.
|
||||
- `MXML_SAX_EVENT_DATA`: Data (
|
||||
--------------------, integer, opaque, real, or text) was just read.
|
||||
- `MXML_SAX_EVENT_DATA`: Data (integer, opaque, real, or text) was just read.
|
||||
- `MXML_SAX_EVENT_DECLARATION`: A declaration was just read.
|
||||
- `MXML_SAX_EVENT_DIRECTIVE`: A processing directive/instruction was just read.
|
||||
- `MXML_SAX_EVENT_ELEMENT_CLOSE` - A close element was just read \(`</element>`)
|
||||
@ -1200,12 +1203,14 @@ using the `mxmlRetain` function. For example, the following SAX callback will
|
||||
retain all nodes, effectively simulating a normal in-memory load:
|
||||
|
||||
```c
|
||||
void
|
||||
bool
|
||||
sax_cb(mxml_node_t *node, mxml_sax_event_t event,
|
||||
void *data)
|
||||
{
|
||||
if (event != MXML_SAX_ELEMENT_CLOSE)
|
||||
mxmlRetain(node);
|
||||
|
||||
return (true);
|
||||
}
|
||||
```
|
||||
|
||||
@ -1216,7 +1221,7 @@ will retain the title and headings in an XHTML file. It also retains the
|
||||
directives like `<?xml ... ?>` and declarations like `<!DOCTYPE ... >`:
|
||||
|
||||
```c
|
||||
void
|
||||
bool
|
||||
sax_cb(mxml_node_t *node, mxml_sax_event_t event,
|
||||
void *data)
|
||||
{
|
||||
@ -1256,6 +1261,8 @@ sax_cb(mxml_node_t *node, mxml_sax_event_t event,
|
||||
mxmlRetain(node);
|
||||
}
|
||||
}
|
||||
|
||||
return (true);
|
||||
}
|
||||
```
|
||||
|
||||
@ -1320,7 +1327,8 @@ Migrating from Mini-XML v3.x
|
||||
|
||||
The following incompatible API changes were made in Mini-XML v4.0:
|
||||
|
||||
- SAX events are not named `MXML_SAX_EVENT_foo` instead of `MXML_SAX_foo`.
|
||||
- SAX events are now named `MXML_SAX_EVENT_foo` instead of `MXML_SAX_foo`.
|
||||
- SAX callbacks now return a boolean value.
|
||||
- Node types are now named `MXML_TYPE_foo` instead of `MXML_foo`.
|
||||
- Functions that returned `0` on success and `-1` on error now return `true` on
|
||||
success and `false` on error.
|
||||
|
@ -1,4 +1,4 @@
|
||||
.TH mxml 3 "Mini-XML API" "2024-03-02" "Mini-XML API"
|
||||
.TH mxml 3 "Mini-XML API" "2024-03-04" "Mini-XML API"
|
||||
.SH NAME
|
||||
mxml \- Mini-XML API
|
||||
.SH INCLUDE FILE
|
||||
@ -157,13 +157,13 @@ functions retrieve the value from a node:
|
||||
|
||||
mxml_node_t *node;
|
||||
|
||||
int intvalue = mxmlGetInteger(node);
|
||||
long intvalue = mxmlGetInteger(node);
|
||||
|
||||
const char *opaquevalue = mxmlGetOpaque(node);
|
||||
|
||||
double realvalue = mxmlGetReal(node);
|
||||
|
||||
int whitespacevalue;
|
||||
bool whitespacevalue;
|
||||
const char *textvalue = mxmlGetText(node, &whitespacevalue);
|
||||
.fi
|
||||
.PP
|
||||
@ -1505,7 +1505,7 @@ typedef const char *(*)(mxml_node_t *, int) mxml_save_cb_t;
|
||||
SAX callback function
|
||||
.PP
|
||||
.nf
|
||||
typedef void(*)(mxml_node_t *, mxml_sax_event_t, void *) mxml_sax_cb_t;
|
||||
typedef bool(*)(mxml_node_t *, mxml_sax_event_t, void *) mxml_sax_cb_t;
|
||||
.fi
|
||||
.SS mxml_sax_event_t
|
||||
SAX event type.
|
||||
|
BIN
doc/mxml.epub
BIN
doc/mxml.epub
Binary file not shown.
@ -437,7 +437,7 @@ span.string {
|
||||
<pre><code>gcc -o myprogram myprogram.c -lmxml
|
||||
</code></pre>
|
||||
<p>If you have the <code>pkg-config</code> software installed, you can use it to determine the proper compiler and linker options for your installation:</p>
|
||||
<pre><code>gcc `pkg-config --cflags mxml` -o myprogram myprogram.c `pkg-config --libs mxml`
|
||||
<pre><code>gcc `pkg-config --cflags mxml4` -o myprogram myprogram.c `pkg-config --libs mxml4`
|
||||
</code></pre>
|
||||
<h3 class="title" id="loading-an-xml-file">Loading an XML File</h3>
|
||||
<p>You load an XML file using the <code>mxmlLoadFile</code> function:</p>
|
||||
@ -1151,12 +1151,15 @@ mxmlSAXLoadString(mxml_node_t *top, <span class="reserved">const</span> <span cl
|
||||
mxml_type_t (*cb)(mxml_node_t *),
|
||||
mxml_sax_cb_t sax, <span class="reserved">void</span> *sax_data);
|
||||
</code></pre>
|
||||
<p>Each function works like the corresponding <code>mxmlLoad</code> function but uses a callback to process each node as it is read. The callback function receives the node, an event code, and a user data pointer you supply:</p>
|
||||
<pre><code class="language-c"><span class="reserved">void</span>
|
||||
<p>Each function works like the corresponding <code>mxmlLoad</code> function but uses a callback to process each node as it is read. The callback function receives the node, an event code, and a user data pointer you supply and returns <code>true</code> to continue processing or <code>false</code> to stop:</p>
|
||||
<pre><code class="language-c"><span class="reserved">bool</span>
|
||||
sax_cb(mxml_node_t *node, mxml_sax_event_t event,
|
||||
<span class="reserved">void</span> *data)
|
||||
{
|
||||
... <span class="reserved">do</span> something ...
|
||||
|
||||
<span class="comment">// Continue processing...</span>
|
||||
<span class="reserved">return</span> (<span class="reserved">true</span>);
|
||||
}
|
||||
</code></pre>
|
||||
<p>The event will be one of the following:</p>
|
||||
@ -1165,7 +1168,7 @@ sax_cb(mxml_node_t *node, mxml_sax_event_t event,
|
||||
</li>
|
||||
<li><p><code>MXML_SAX_EVENT_COMMENT</code>: A comment was just read.</p>
|
||||
</li>
|
||||
<li><p><code>MXML_SAX_EVENT_DATA</code>: Data ( --------------------, integer, opaque, real, or text) was just read.</p>
|
||||
<li><p><code>MXML_SAX_EVENT_DATA</code>: Data (integer, opaque, real, or text) was just read.</p>
|
||||
</li>
|
||||
<li><p><code>MXML_SAX_EVENT_DECLARATION</code>: A declaration was just read.</p>
|
||||
</li>
|
||||
@ -1177,16 +1180,18 @@ sax_cb(mxml_node_t *node, mxml_sax_event_t event,
|
||||
</li>
|
||||
</ul>
|
||||
<p>Elements are <em>released</em> after the close element is processed. All other nodes are released after they are processed. The SAX callback can <em>retain</em> the node using the <code>mxmlRetain</code> function. For example, the following SAX callback will retain all nodes, effectively simulating a normal in-memory load:</p>
|
||||
<pre><code class="language-c"><span class="reserved">void</span>
|
||||
<pre><code class="language-c"><span class="reserved">bool</span>
|
||||
sax_cb(mxml_node_t *node, mxml_sax_event_t event,
|
||||
<span class="reserved">void</span> *data)
|
||||
{
|
||||
<span class="reserved">if</span> (event != MXML_SAX_ELEMENT_CLOSE)
|
||||
mxmlRetain(node);
|
||||
|
||||
<span class="reserved">return</span> (<span class="reserved">true</span>);
|
||||
}
|
||||
</code></pre>
|
||||
<p>More typically the SAX callback will only retain a small portion of the document that is needed for post-processing. For example, the following SAX callback will retain the title and headings in an XHTML file. It also retains the (parent) elements like <code><html></code>, <code><head></code>, and <code><body></code>, and processing directives like <code><?xml ... ?></code> and declarations like <code><!DOCTYPE ... ></code>:</p>
|
||||
<pre><code class="language-c"><span class="reserved">void</span>
|
||||
<pre><code class="language-c"><span class="reserved">bool</span>
|
||||
sax_cb(mxml_node_t *node, mxml_sax_event_t event,
|
||||
<span class="reserved">void</span> *data)
|
||||
{
|
||||
@ -1226,6 +1231,8 @@ sax_cb(mxml_node_t *node, mxml_sax_event_t event,
|
||||
mxmlRetain(node);
|
||||
}
|
||||
}
|
||||
|
||||
<span class="reserved">return</span> (<span class="reserved">true</span>);
|
||||
}
|
||||
</code></pre>
|
||||
<p>The resulting skeleton document tree can then be searched just like one loaded using the <code>mxmlLoad</code> functions. For example, a filter that reads an XHTML document from stdin and then shows the title and headings in the document would look like:</p>
|
||||
@ -1277,7 +1284,9 @@ print_children(mxml_node_t *parent)
|
||||
<h2 class="title" id="migrating-from-mini-xml-v3.x">Migrating from Mini-XML v3.x</h2>
|
||||
<p>The following incompatible API changes were made in Mini-XML v4.0:</p>
|
||||
<ul>
|
||||
<li><p>SAX events are not named <code>MXML_SAX_EVENT_foo</code> instead of <code>MXML_SAX_foo</code>.</p>
|
||||
<li><p>SAX events are now named <code>MXML_SAX_EVENT_foo</code> instead of <code>MXML_SAX_foo</code>.</p>
|
||||
</li>
|
||||
<li><p>SAX callbacks now return a boolean value.</p>
|
||||
</li>
|
||||
<li><p>Node types are now named <code>MXML_TYPE_foo</code> instead of <code>MXML_foo</code>.</p>
|
||||
</li>
|
||||
@ -2874,7 +2883,7 @@ typedef const char *(*mxml_save_cb_t)(<a href="#mxml_node_t">mxml_node_t</a> *,
|
||||
<h3 class="typedef"><a id="mxml_sax_cb_t">mxml_sax_cb_t</a></h3>
|
||||
<p class="description">SAX callback function</p>
|
||||
<p class="code">
|
||||
typedef void (*mxml_sax_cb_t)(<a href="#mxml_node_t">mxml_node_t</a> *, mxml_sax_event_t, void *);
|
||||
typedef bool (*mxml_sax_cb_t)(<a href="#mxml_node_t">mxml_node_t</a> *, mxml_sax_event_t, void *);
|
||||
</p>
|
||||
<h3 class="typedef"><a id="mxml_sax_event_t">mxml_sax_event_t</a></h3>
|
||||
<p class="description">SAX event type.</p>
|
||||
|
29
mxml-file.c
29
mxml-file.c
@ -1341,7 +1341,8 @@ mxml_load_data(
|
||||
|
||||
if (sax_cb)
|
||||
{
|
||||
(*sax_cb)(node, MXML_SAX_EVENT_DATA, sax_data);
|
||||
if (!(*sax_cb)(node, MXML_SAX_EVENT_DATA, sax_data))
|
||||
goto error;
|
||||
|
||||
if (!mxmlRelease(node))
|
||||
node = NULL;
|
||||
@ -1367,7 +1368,8 @@ mxml_load_data(
|
||||
|
||||
if (sax_cb)
|
||||
{
|
||||
(*sax_cb)(node, MXML_SAX_EVENT_DATA, sax_data);
|
||||
if (!(*sax_cb)(node, MXML_SAX_EVENT_DATA, sax_data))
|
||||
goto error;
|
||||
|
||||
if (!mxmlRelease(node))
|
||||
node = NULL;
|
||||
@ -1464,7 +1466,8 @@ mxml_load_data(
|
||||
|
||||
if (sax_cb)
|
||||
{
|
||||
(*sax_cb)(node, MXML_SAX_EVENT_COMMENT, sax_data);
|
||||
if (!(*sax_cb)(node, MXML_SAX_EVENT_COMMENT, sax_data))
|
||||
goto error;
|
||||
|
||||
if (!mxmlRelease(node))
|
||||
node = NULL;
|
||||
@ -1520,7 +1523,8 @@ mxml_load_data(
|
||||
|
||||
if (sax_cb)
|
||||
{
|
||||
(*sax_cb)(node, MXML_SAX_EVENT_CDATA, sax_data);
|
||||
if (!(*sax_cb)(node, MXML_SAX_EVENT_CDATA, sax_data))
|
||||
goto error;
|
||||
|
||||
if (!mxmlRelease(node))
|
||||
node = NULL;
|
||||
@ -1570,7 +1574,8 @@ mxml_load_data(
|
||||
|
||||
if (sax_cb)
|
||||
{
|
||||
(*sax_cb)(node, MXML_SAX_EVENT_DIRECTIVE, sax_data);
|
||||
if (!(*sax_cb)(node, MXML_SAX_EVENT_DIRECTIVE, sax_data))
|
||||
goto error;
|
||||
|
||||
if (strncmp(node->value.directive, "xml ", 4) && !mxmlRelease(node))
|
||||
node = NULL;
|
||||
@ -1645,7 +1650,8 @@ mxml_load_data(
|
||||
|
||||
if (sax_cb)
|
||||
{
|
||||
(*sax_cb)(node, MXML_SAX_EVENT_DECLARATION, sax_data);
|
||||
if (!(*sax_cb)(node, MXML_SAX_EVENT_DECLARATION, sax_data))
|
||||
goto error;
|
||||
|
||||
if (!mxmlRelease(node))
|
||||
node = NULL;
|
||||
@ -1686,7 +1692,8 @@ mxml_load_data(
|
||||
|
||||
if (sax_cb)
|
||||
{
|
||||
(*sax_cb)(node, MXML_SAX_EVENT_ELEMENT_CLOSE, sax_data);
|
||||
if (!(*sax_cb)(node, MXML_SAX_EVENT_ELEMENT_CLOSE, sax_data))
|
||||
goto error;
|
||||
|
||||
if (!mxmlRelease(node))
|
||||
{
|
||||
@ -1737,7 +1744,10 @@ mxml_load_data(
|
||||
}
|
||||
|
||||
if (sax_cb)
|
||||
(*sax_cb)(node, MXML_SAX_EVENT_ELEMENT_OPEN, sax_data);
|
||||
{
|
||||
if (!(*sax_cb)(node, MXML_SAX_EVENT_ELEMENT_OPEN, sax_data))
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (!first)
|
||||
first = node;
|
||||
@ -1757,7 +1767,8 @@ mxml_load_data(
|
||||
}
|
||||
else if (sax_cb)
|
||||
{
|
||||
(*sax_cb)(node, MXML_SAX_EVENT_ELEMENT_CLOSE, sax_data);
|
||||
if (!(*sax_cb)(node, MXML_SAX_EVENT_ELEMENT_CLOSE, sax_data))
|
||||
goto error;
|
||||
|
||||
if (!mxmlRelease(node))
|
||||
{
|
||||
|
2
mxml.h
2
mxml.h
@ -120,7 +120,7 @@ typedef mxml_type_t (*mxml_load_cb_t)(mxml_node_t *);
|
||||
typedef const char *(*mxml_save_cb_t)(mxml_node_t *, int);
|
||||
// Save callback function
|
||||
|
||||
typedef void (*mxml_sax_cb_t)(mxml_node_t *, mxml_sax_event_t, void *);
|
||||
typedef bool (*mxml_sax_cb_t)(mxml_node_t *, mxml_sax_event_t, void *);
|
||||
// SAX callback function
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user