source: project/wiki/eggref/5/sxml-modifications @ 38618

Last change on this file since 38618 was 38618, checked in by Vasilij Schneidermann, 12 months ago

Fix broken links

File size: 8.7 KB
Line 
1[[tags:eggs]]
2
3This is version 0.3 of the '''sxml-modifications''' extension library for Chicken Scheme.
4
5[[toc:]]
6
7== Sxml-modifications
8
9The {{modif}} parts of the [[http://cvs.sourceforge.net/viewcvs.py/ssax/sxml-tools/|sxml-tools]] from the [[http://ssax.sf.net|SSAX project]] at Sourceforge.
10
11== Requirements
12
13* [[srfi-1]]
14* [[sxpath]]
15
16== Documentation
17
18This egg provides procedures for making modifications to SXML
19documents, functional-style.
20
21Some documentation is available in
22[[https://web.archive.org/web/20170608200039/http://modis.ispras.ru/Lizorkin/sxml-tutorial.html#hevea:modif|Dmitry
23Lizorkin's tutorial]] and the [[http://ssax.sf.net|SSAX homepage]].
24Note that the SSAX documentation uses the more awkward and arbitrary
25{{sxml:}} or {{modif:}} prefixes.
26
27The initial documentation on this wiki page came straight from the
28comments in the extremely well-documented source code. It's
29recommended you read the code if you want to learn more.
30
31Modifications are done to all nodes that match an xpath expression.
32These can be either textual "standard" XPath or [[sxpath]]
33expressions.
34
35<procedure>(sxml-modify [update-specifier ...])</procedure>
36
37Returns a procedure which accepts a document and returns a modified
38copy of this document.  How it will be modified depends on the
39{{update-specifier}}s passed to it.  Each update-specifier is a list
40of two or three elements:
41
42  update-specifier ::= (xpath-location-path  action  [action-parameter ...])
43
44{{xpath-location-path}} addresses the node(s) to be transformed, in
45the form of an XPath location path. If the location path is absolute,
46it addresses the node(s) with respect to the root of the document
47being transformed. If the location path is relative, it addresses the
48node(s) with respect to the node selected by the previous
49update-specifier. The location path in the first update-specifier
50always addresses the node(s) with respect to the root of the
51document. We'll further refer to the node with respect of which the
52location path is evaluated as to the base-node for this location path.
53
54{{action}} specifies the modification to be made over each of the
55node(s) addressed by the location path. Possible actions are described
56below.
57
58{{action-parameter}}s are additional parameters supplied for the
59action. The number of parameters and their semantics depend on the
60definite action.
61
62Each {{action}} is either a symbol that describes what to do, or a
63handler lambda which performs the action itself.  The allowed symbols
64are as follows:
65
66; {{delete}} : deletes the node. Expects no action-parameters
67; {{delete-undeep}} : deletes the node, but keeps all its content (which thus moves to one level upwards in the document tree). Expects no action-parameters.
68; {{insert-into}} : inserts the new node(s) as the last children of the given node. The new node(s) are specified in SXML as action-parameters.
69; {{insert-following}}, {{insert-preceding}} : inserts the new node(s) after (before) the given node. Action-parameters are the same as for {{insert-into}}.
70; {{replace}} : replaces the given node with the new node(s). Action-parameters are the same as for {{insert-into}}.
71; {{rename}} : renames the given node. The node to be renamed must be a pair (i.e. not a text node). A single action-parameter is expected, which is to be a Scheme symbol to specify the new name of the given node.
72; {{move-into}} : moves the given node to a new location. The single action-parameter is the location path, which addresses the new location with respect to the given node as the base node. The given node becomes the last child of the node selected by the parameter location path.
73; {{move-following}}, {{move-preceding}} : the given node is moved to the location respectively after (before) the node selected by the parameter location path.
74
75If a handler is passed, it should look like {{(lambda (node context base-node) ...)}}.
76The {{node}} is the current target of the {{xpath-location-path}} in the current
77update specifier.  {{context}} is a list that consists of the symbol {{*CONTEXT*}}, followed by
78the current node and all its ancestors that were looked at during the XPath matching process
79(as per [[sxpath]]'s {{context-sxpath}} module).  {{base-node}} is the node that was used
80as the starting point for the current {{xpath-location-path}} (useful if it's a relative
81path; you can "see" the previous update specifier's node this way).
82
83The handler can return either an SXML node, which will then replace
84the source document's node, or a nodeset (list of nodes), in which
85case it will splice this set into the place occupied by the source
86node.  If an empty nodeset -- ie, {{'()}} -- is returned, this has the
87effect of deleting the source node.
88
89Example:
90
91<enscript highlight="scheme">
92(define doc
93  '(*TOP*
94    (*PI* xml "version='1.0'")
95    (purchaseOrder (@ (orderDate "07.23.2001"))
96      (recipient
97        (name "Dennis Scannell")
98        (street "175 Perry Lea Side Road"))
99      (order
100        (cd (@ (title "Little Lion") (artist "Brooks Williams")))))))
101
102(define delete-recipient (sxml-modify '("purchaseOrder/recipient" delete)))
103(delete-recipient doc)
104=>
105(*TOP*
106 (*PI* xml "version='1.0'")
107 (purchaseOrder (@ (orderDate "07.23.2001"))
108   ;; (recipient ...) is gone
109   (order
110     (cd (@ (title "Little Lion") (artist "Brooks Williams"))))))
111
112;; insert-into accepts any number of action-parameters, being the node(s) to insert at the end
113((sxml-modify '("purchaseOrder/recipient" insert-into (postalCode "05676") (city "Footown"))) doc)
114=>
115(*TOP*
116 (*PI* xml "version='1.0'")
117 (purchaseOrder (@ (orderDate "07.23.2001"))
118   (recipient
119     (name "Dennis Scannell")
120     (street "175 Perry Lea Side Road")
121     (postalCode "05676") ; New
122     (city "Footown"))    ; New
123   (order
124     (cd (@ (title "Little Lion") (artist "Brooks Williams"))))))
125</enscript>
126
127<procedure>(sxml-modify! [update-specifier ...])</procedure>
128
129Destructively updating version of {{sxml-modify}}.  Like the
130linear-updating variants of SRFI-1, you should use the return value of
131this procedure rather than assuming the original document was mutated
132in-place.
133
134<procedure>(sxml-insert-following node-specifier)</procedure>
135<procedure>(sxml-insert-preceding node-specifier)</procedure>
136<procedure>(sxml-insert-into node-specifier)</procedure>
137<procedure>(sxml-rename new-name)</procedure>
138<procedure>sxml-delete</procedure>
139<procedure>sxml-delete-undeep</procedure>
140
141These procedures all correspond to the action symbols accepted by
142{{sxml-modify}}.  There are no procedures corresponding to
143{{move-into}}, {{move-preceding}}, {{move-following}} or {{replace}}.
144
145The {{sxml-delete}} and {{sxml-delete-undeep}} procedures can only be
146put directly into the action-parameters list as-is, which means this
147adds zero expressiveness over the corresponding symbols.
148
149The {{insert-following}}, {{insert-preceding}} and {{insert-into}}
150procedures all accept a {{node-specifier}} procedure of two arguments
151which must return a node or node-set which shall be inserted.  The
152first argument of the procedure is the context, the second is the base
153node.
154
155The {{sxml-rename}} procedure accepts a symbol which indicates the new
156element name to use for the matched nodes.
157
158Here's the example from {{sxml-modify}} using these procedures instead
159of action symbols:
160
161<enscript highlight="scheme">
162(define doc
163  '(*TOP*
164    (*PI* xml "version='1.0'")
165    (purchaseOrder (@ (orderDate "07.23.2001"))
166      (recipient
167        (name "Dennis Scannell")
168        (street "175 Perry Lea Side Road"))
169      (order
170        (cd (@ (title "Little Lion") (artist "Brooks Williams")))))))
171
172(define delete-recipient (sxml-modify `("purchaseOrder/recipient" ,sxml-delete)))
173(delete-recipient doc)
174=>
175(*TOP*
176 (*PI* xml "version='1.0'")
177 (purchaseOrder (@ (orderDate "07.23.2001"))
178   ;; (recipient ...) is gone
179   (order
180     (cd (@ (title "Little Lion") (artist "Brooks Williams"))))))
181
182;; insert-into accepts any number of action-parameters, being the node(s) to insert at the end
183((sxml-modify `("purchaseOrder/recipient"
184                ,(sxml-insert-into
185                  (lambda (context base-node)
186                    (list '(postalCode "05676") '(city "Footown"))))))
187 doc)
188=>
189(*TOP*
190 (*PI* xml "version='1.0'")
191 (purchaseOrder (@ (orderDate "07.23.2001"))
192   (recipient
193     (name "Dennis Scannell")
194     (street "175 Perry Lea Side Road")
195     (postalCode "05676") ; New
196     (city "Footown"))    ; New
197   (order
198     (cd (@ (title "Little Lion") (artist "Brooks Williams"))))))
199</enscript>
200
201== About this egg
202
203=== Author
204
205[[http://okmij.org/ftp/|Oleg Kiselyov]], [[http://metapaper.net/|Kirill Lisovsky]], [[https://web.archive.org/web/20171030192758/http://modis.ispras.ru/Lizorkin/|Dmitry Lizorkin]].
206
207=== Version history
208
209; 0.3 : Add sxml- prefix to all exported functions
210; 0.2 : Ported to Chicken 5
211; 0.1 : First Chicken 4 release
212
213=== License
214
215The sxml-tools are in the public domain.
Note: See TracBrowser for help on using the repository browser.