|
1 | 1 | # XML-parser
|
2 |
| -Work in progress. Lightweight xml-parser with minimal system requirements. |
| 2 | + |
| 3 | +Work in progress. Lightweight xml-parser for microcontrollers. |
3 | 4 |
|
4 | 5 |
|
5 | 6 | # Usage
|
6 | 7 |
|
7 |
| -Example program: |
| 8 | +Example of parsing string: |
8 | 9 |
|
9 | 10 | ```c
|
10 |
| -static const PARSER_XML_NAME elements[]= |
11 |
| -{ |
12 |
| - // Predefined element and attribute names. |
13 |
| - |
14 |
| - { "ELEM_type_1" }, |
15 |
| - { "ELEM_type_2" }, |
16 |
| - { "ELEM_type_3" }, |
| 11 | +// List of element and attribute names in test string. |
17 | 12 |
|
18 |
| - { "testElementId" }, |
19 |
| - { "intAttribute" }, |
20 |
| - { "floatAttribute" }, |
21 |
| - { "stringAttribute" }, |
| 13 | +static const PARSER_XML_NAME xml_names[]= |
| 14 | +{ |
| 15 | + { "element_type_1" }, |
| 16 | + { "element_type_2" }, |
| 17 | + { "element_type_3" }, |
| 18 | + { "element_type_4" }, |
| 19 | + { "element_type_5" }, |
| 20 | + { "element_type_6" }, |
| 21 | + { "element_type_7" }, |
| 22 | + |
| 23 | + { "testElementId" }, |
| 24 | + { "intAttribute" }, |
| 25 | + { "floatAttribute" }, |
| 26 | + { "stringAttribute" }, |
22 | 27 | };
|
23 | 28 |
|
24 |
| -// Test string to parse |
| 29 | +// String to parse. |
25 | 30 |
|
26 |
| -static const char test_1[]= |
| 31 | +static const char parse_test_string[]= |
27 | 32 | {
|
28 |
| -"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" |
29 |
| -"\n" |
30 |
| -"<ELEM_type_1 testElementId='0' intAttribute='20' floatAttribute='1.23' stringAttribute=\"TEST\">\n" |
31 |
| -"\n" |
32 |
| -" <!-- Single line comment -->\n" |
33 |
| -" <ELEM_type_2 testElementId='1'>\n" |
34 |
| -" <ELEM_type_3 testElementId='11'/>\n" |
35 |
| -" <ELEM_type_3 testElementId='12'/>\n" |
36 |
| -" <ELEM_type_3 testElementId='13'/>\n" |
37 |
| -"\n" |
38 |
| -" <!-- Single line comment -->\n" |
39 |
| -" <ELEM_type_3 testElementId='14'>\n" |
40 |
| -" <!-- Multiline\n" |
41 |
| -" comment -->\n" |
42 |
| -" </ELEM_type_3>\n" |
43 |
| -" </ELEM_type_2>\n" |
44 |
| -"\n" |
45 |
| -" <ELEM_type_2 testElementId='2'>Child element with string content</ELEM_type_2>\n" |
46 |
| -"</ELEM_type_1>\n" |
47 |
| -"" |
| 33 | +"<element_type_1 testElementId=\"0\" intAttribute=\"20\" floatAttribute=\"1.230000\" stringAttribute=\"TEST\">\n" |
| 34 | +" <element_type_2 testElementId=\"1\">\n" |
| 35 | +" <element_type_3 testElementId=\"11\"/>\n" |
| 36 | +" <element_type_3 testElementId=\"12\"/>\n" |
| 37 | +" <element_type_3 testElementId=\"13\"/>\n" |
| 38 | +" <element_type_3 testElementId=\"14\"/>\n" |
| 39 | +" </element_type_2>\n" |
| 40 | +" <element_type_4>\n" |
| 41 | +" <element_type_5>\n" |
| 42 | +" <element_type_6 testElementId=\"15\"/>\n" |
| 43 | +" <element_type_6 testElementId=\"17\"/>\n" |
| 44 | +" </element_type_5>\n" |
| 45 | +" </element_type_4>\n" |
| 46 | +" <element_type_7>\n" |
| 47 | +" <element_type_8 testElementId=\"18\"/>\n" |
| 48 | +" </element_type_7>\n" |
| 49 | +"</element_type_1>\n" |
48 | 50 | };
|
49 | 51 |
|
50 |
| -int main(void) |
| 52 | +static PARSER_ERROR test_parse(void) |
51 | 53 | {
|
52 | 54 | PARSER_XML* xml;
|
53 |
| - PARSER_CHAR out[1024]; |
54 |
| - PARSER_INT bw; |
| 55 | + PARSER_CHAR buffer_out[1024]; |
| 56 | + PARSER_INT buffer_lenght; |
| 57 | + PARSER_INT bytes_written; |
55 | 58 | PARSER_ERROR error;
|
56 | 59 |
|
57 | 60 | // Initialize xml-struct.
|
58 | 61 |
|
59 | 62 | xml= parser_begin();
|
60 | 63 | if ( !xml )
|
61 |
| - { |
62 |
| - printf("%s %d: XML-struct initialization failed.\n", __FUNCTION__, __LINE__); |
63 | 64 | return(1);
|
64 |
| - } |
65 | 65 |
|
66 |
| - // Parse xml-string. |
| 66 | + // Parse string. |
67 | 67 |
|
68 |
| - error= parser_parse_string(xml, test_1, elements, sizeof(elements)/sizeof(PARSER_XML_NAME)); |
| 68 | + error= parser_parse_string(xml, parse_test_string, strlen(parse_test_string), xml_names, sizeof(xml_names)/sizeof(PARSER_XML_NAME)); |
69 | 69 | if ( error )
|
70 |
| - { |
71 |
| - printf("%d %s: Error parsing xml-string.", __FUNCTION__, __LINE__); |
72 |
| - goto end; |
73 |
| - } |
| 70 | + return(error); |
74 | 71 |
|
75 | 72 | // End parsing.
|
76 | 73 |
|
77 | 74 | error= parser_finalize(xml);
|
78 |
| - if ( !error ) |
79 |
| - { |
80 |
| - // Write parsed xml back to string. |
| 75 | + if ( error ) |
| 76 | + return(error); |
81 | 77 |
|
82 |
| - error= parser_write_xml_to_buffer(xml, elements, out, sizeof(out), &bw, 0); |
83 |
| - if ( !error ) |
84 |
| - printf("Bytes written:%d Buffer content:\n%s", bw, out); |
85 |
| - } |
| 78 | + // Write parsed xml back to string. |
| 79 | + |
| 80 | + error= parser_write_xml_to_buffer(xml, xml_names, buffer_out, sizeof(buffer_out), &bytes_written, 0); |
| 81 | + if ( error ) |
| 82 | + return(error); |
86 | 83 |
|
87 |
| - end: |
| 84 | + // Check that output buffer matches original string. |
| 85 | + |
| 86 | + if ( strncmp(buffer_out, parse_test_string, sizeof(buffer_out)) ) |
| 87 | + { |
| 88 | + printf("%s %d: Parse result error: input and output string does not match.\n", __FUNCTION__, __LINE__); |
| 89 | + printf("Original string:\n%s\n\n", parse_test_string); |
| 90 | + printf("Output buffer string:\n%s\n\n", buffer_out); |
| 91 | + } |
88 | 92 |
|
89 | 93 | // Free xml.
|
90 | 94 |
|
91 |
| - if ( xml ) |
92 |
| - parser_free_xml(xml); |
| 95 | + error= parser_free_xml(xml); |
| 96 | + if ( error ) |
| 97 | + return(error); |
93 | 98 |
|
94 | 99 | return(0);
|
95 | 100 | }
|
|
0 commit comments