-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathxml2.scm
150 lines (118 loc) · 3.74 KB
/
xml2.scm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
(c-declare #<<c-declare-end
#include <libxml/tree.h>
#include <libxml/parser.h>
c-declare-end
)
(c-define-type xmlDoc (pointer "xmlDoc"))
(c-define-type xmlNode (pointer "xmlNode"))
(c-define-type xmlAttribute (pointer "xmlAttribute"))
(define xml:parse-file
(c-lambda (nonnull-char-string)
xmlDoc
"xmlParseFile"))
(define xml:root-element
(c-lambda (xmlDoc)
xmlNode
"xmlDocGetRootElement"))
(define xml:free-doc
(c-lambda (xmlDoc)
void
"xmlFreeDoc"))
(define xml:node-children
(c-lambda (xmlNode)
xmlNode
"___result_voidstar = ___arg1->children;"))
(define xml:node-next
(c-lambda (xmlNode)
xmlNode
"___result_voidstar = ___arg1->next;"))
(define xml:node-name
(c-lambda (xmlNode)
nonnull-char-string
"___result = ___arg1->name;"))
(define xml:node-content
(c-lambda (xmlNode)
nonnull-char-string
"___result = ___arg1->content;"))
(define xml:node-properties
(c-lambda (xmlNode)
xmlAttribute
"___result_voidstar = ___arg1->properties;"))
(define xml:node-type
(c-lambda (xmlNode)
int
"___result = ___arg1->type;"))
(define xml:node-doc
(c-lambda (xmlNode)
xmlDoc
"___result_voidstar = ___arg1->doc;"))
(define xml:node-list-string
(c-lambda (xmlDoc xmlNode int)
nonnull-char-string
"xmlNodeListGetString"))
(define xml:ELEMENT-NODE
((c-lambda () int "___result = XML_ELEMENT_NODE;")))
(define xml:attr-name
(c-lambda (xmlAttribute)
nonnull-char-string
"___result = ___arg1->name;"))
(define xml:attr-children
(c-lambda (xmlAttribute)
xmlNode
"___result_voidstar = ___arg1->children;"))
(define xml:attr-next
(c-lambda (xmlAttribute)
xmlAttribute
"___result_voidstar = ___arg1->next;"))
(define (xml:node->attr-alist node)
(let loop ((result '())
(attr (xml:node-properties node)))
(if attr
(loop (cons (cons (xml:attr-name attr)
(xml:node-list-string (xml:node-doc node)
(xml:attr-children attr)
1))
result)
(xml:attr-next attr))
result)))
(define (call-with-links head next-fn call-fn)
(let loop ((head head))
(if head
(begin
(call-fn head)
(loop (next-fn head))))))
(define (xml:node->list node)
(let ((result '()))
(call-with-links node xml:node-next
(lambda (node)
(set! result (cons node result))))
(reverse result)))
(define (xml:element? node)
(= (xml:node-type node) xml:ELEMENT-NODE))
(define (sml:make node-name node-attr-alist children)
(cons node-name (cons node-attr-alist children)))
(define (sml:name exp) (car exp))
(define (sml:attrs exp) (cadr exp))
(define (sml:attr exp attr)
(let ((a (assoc attr (sml:attrs exp))))
(if a (cdr a) #f)))
(define (sml:children exp) (cddr exp))
(define (xml->sml-internal node)
(map (lambda (node)
(sml:make (xml:node-name node)
(xml:node->attr-alist node)
(xml->sml-internal (xml:node-children node))))
(filter xml:element? (xml:node->list node))))
(define (xml->sml node)
(car (xml->sml-internal node)))
(define (sml:node-named? name)
(lambda (node)
(equal? (sml:name node) name)))
(define (sml:parse-file filename)
(let* ((doc (xml:parse-file filename))
(node (if doc
(xml:root-element doc)
(error "failed to load " filename)))
(scml (xml->sml node)))
(xml:free-doc doc)
scml))