1 |
joko |
1.1 |
<?xml version="1.0" encoding="ISO-8859-1"?> |
2 |
|
|
|
3 |
|
|
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> |
4 |
|
|
|
5 |
|
|
<!-- |
6 |
|
|
|
7 |
|
|
Purpose of this XML Stylesheet is to implement a set of templates |
8 |
|
|
to do simple xml node manipulation. (kinda XML API) |
9 |
|
|
Main target is "flexible insertion of new xml child nodes". |
10 |
|
|
|
11 |
|
|
If this attempt works out well, it will be continued by a follow-up |
12 |
|
|
trying to implement XUpdate in XSLT. |
13 |
|
|
|
14 |
|
|
|
15 |
|
|
References: |
16 |
|
|
- XUpdate: |
17 |
|
|
Requirements: http://www.xmldb.org/xupdate/xupdate-req.html |
18 |
|
|
Working Draft: http://www.xmldb.org/xupdate/xupdate-wd.html |
19 |
|
|
- XML API: |
20 |
|
|
- XML::XUpdate::LibXML: http://search.cpan.org/author/PAJAS/XML-XUpdate-LibXML-0.4.0/lib/XML/XUpdate/LibXML.pm |
21 |
|
|
- XSL / XSLT: |
22 |
|
|
http://www.w3.org/TR/xslt |
23 |
|
|
http://www.xsl-rp.de/ |
24 |
|
|
http://xml.klute-thiemann.de/w3c-de/REC-xslt-20020318/ |
25 |
|
|
http://xmlxslt.sourceforge.net/ |
26 |
|
|
- misc pointers: |
27 |
|
|
"Re: Modify XML documents": http://aspn.activestate.com/ASPN/Mail/Message/perl-xml/1265431 |
28 |
|
|
XSL Extensions: http://xmlsoft.org/XSLT/extensions.html |
29 |
|
|
EXSLT: http://www.exslt.org/set/functions/difference/index.html |
30 |
|
|
"how to insert element at required position in document tree?": http://p2p.wrox.com/archive/xslt/2001-06/98.asp |
31 |
|
|
XML APIs for Databases: http://www.javaworld.com/javaworld/jw-01-2000/jw-01-dbxml.html |
32 |
|
|
|
33 |
|
|
--> |
34 |
|
|
|
35 |
|
|
<xsl:output method="raw"/> |
36 |
|
|
|
37 |
|
|
<!-- 1. This is the passthru logic (copy all untouched nodes). --> |
38 |
|
|
<xsl:template name="passthru"><xsl:copy><xsl:apply-templates /></xsl:copy></xsl:template> |
39 |
|
|
<!-- activate this --> |
40 |
|
|
<xsl:template match="*"><xsl:call-template name="passthru" /></xsl:template> |
41 |
|
|
<!-- override some builtin rules: see http://www.w3.org/TR/xslt#built-in-rule --> |
42 |
|
|
<xsl:template match="comment()"><xsl:call-template name="passthru" /></xsl:template> |
43 |
|
|
|
44 |
|
|
<!-- 2. This is the crud API. --> |
45 |
|
|
|
46 |
|
|
<!-- 2.a. The context finder. --> |
47 |
|
|
|
48 |
|
|
<!-- query part one: the node name --> |
49 |
|
|
<xsl:template match="source"> |
50 |
|
|
<xsl:choose> |
51 |
|
|
<!-- query part two: the attrib key and value --> |
52 |
|
|
<xsl:when test="@key=expekt"> |
53 |
|
|
<xsl:call-template name="crud" > |
54 |
|
|
<xsl:with-param name="action">CREATE</xsl:with-param> |
55 |
|
|
<xsl:with-param name="mode">callback</xsl:with-param> |
56 |
|
|
<xsl:with-param name="cbname">abc</xsl:with-param> |
57 |
|
|
</xsl:call-template> |
58 |
|
|
</xsl:when> |
59 |
|
|
<xsl:otherwise> |
60 |
|
|
<xsl:call-template name="passthru_kay" /> |
61 |
|
|
</xsl:otherwise> |
62 |
|
|
</xsl:choose> |
63 |
|
|
</xsl:template> |
64 |
|
|
|
65 |
|
|
|
66 |
|
|
<!-- 2.b. The node manipulators: They translate the current context. --> |
67 |
|
|
|
68 |
|
|
<!-- by Mike Kay, Software AG [http://p2p.wrox.com/archive/xslt/2001-06/98.asp] --> |
69 |
|
|
<!-- enhancements & comments: Andreas Motl, rotamente.de --> |
70 |
|
|
<!-- <xsl:template match="source"> --> |
71 |
|
|
<xsl:template name="passthru_kay"> |
72 |
|
|
<xsl:copy> |
73 |
|
|
<xsl:copy-of select="@*" /> |
74 |
|
|
<xsl:apply-templates /> |
75 |
|
|
</xsl:copy> |
76 |
|
|
</xsl:template> |
77 |
|
|
|
78 |
|
|
<xsl:template name="inject_kay_motl"> |
79 |
|
|
<xsl:param name="payload" /> |
80 |
|
|
<xsl:value-of select="$payload" /> |
81 |
|
|
<xsl:copy> |
82 |
|
|
<xsl:copy-of select="@*" /> |
83 |
|
|
<xsl:apply-templates /> |
84 |
|
|
<!-- <xsl:apply-templates select="*[3]" /> --> |
85 |
|
|
<!-- <xsl:value-of select="text()" /> --> |
86 |
|
|
<!-- Multiple handlers here now: a) create fressshhhh element, b) clone s.th. --> |
87 |
|
|
<!-- TODO: Do switch/case or couple of if/then statements here to be able to handle that "at runtime". --> |
88 |
|
|
<xsl:call-template name="create_fresh_element" /> |
89 |
|
|
<xsl:call-template name="clone_last_element" /> |
90 |
|
|
<xsl:call-template name="clone_element_nr" /> |
91 |
|
|
</xsl:copy> |
92 |
|
|
</xsl:template> |
93 |
|
|
|
94 |
|
|
<xsl:template name="crud"> |
95 |
|
|
|
96 |
|
|
<xsl:param name="action" /> |
97 |
|
|
<xsl:param name="payload" /> |
98 |
|
|
<xsl:param name="mode" /> |
99 |
|
|
<xsl:param name="cbname" /> |
100 |
|
|
|
101 |
|
|
<!-- |
102 |
|
|
action: <xsl:value-of select="$action" /> |
103 |
|
|
payload: <xsl:value-of select="$payload" /> |
104 |
|
|
--> |
105 |
|
|
|
106 |
|
|
<!-- |
107 |
|
|
<xsl:if test="$action=5"> |
108 |
|
|
CRUD: CREATE - if |
109 |
|
|
</xsl:if> |
110 |
|
|
--> |
111 |
|
|
|
112 |
|
|
<xsl:copy> |
113 |
|
|
|
114 |
|
|
<xsl:copy-of select="@*" /> |
115 |
|
|
<xsl:apply-templates /> |
116 |
|
|
|
117 |
|
|
<!-- crud action dispatcher --> |
118 |
|
|
<xsl:choose> |
119 |
|
|
|
120 |
|
|
<!-- CREATE --> |
121 |
|
|
<xsl:when test="{$action}=CREATE"> |
122 |
|
|
|
123 |
|
|
<!-- thats a (compact) switch case in xsl lingo! --> |
124 |
|
|
<xsl:choose> |
125 |
|
|
|
126 |
|
|
<xsl:when test="$payload!="> |
127 |
|
|
<xsl:comment> Payload injected on {timestamp} </xsl:comment> |
128 |
|
|
<xsl:value-of select="$payload" /> |
129 |
|
|
</xsl:when> |
130 |
|
|
|
131 |
|
|
<xsl:when test="$mode=callback"> |
132 |
|
|
<xsl:comment> Payload injected via callback <xsl:value-of select="{$cbname}" /> on {$timestamp} </xsl:comment> |
133 |
|
|
<xsl:call-template name="xupdate_element_create_embedded" /> |
134 |
|
|
</xsl:when> |
135 |
|
|
|
136 |
|
|
<xsl:otherwise> |
137 |
|
|
<xsl:comment> Cloned last element as template on {timestamp} </xsl:comment> |
138 |
|
|
<xsl:call-template name="clone_last_element" /> |
139 |
|
|
</xsl:otherwise> |
140 |
|
|
|
141 |
|
|
</xsl:choose> |
142 |
|
|
|
143 |
|
|
</xsl:when> |
144 |
|
|
|
145 |
|
|
<xsl:otherwise> |
146 |
|
|
<xsl:comment> |
147 |
|
|
UNKOWN CRUD ACTION: "<xsl:value-of select="$action" />" on <xsl:value-of select="$now" />. |
148 |
|
|
</xsl:comment> |
149 |
|
|
</xsl:otherwise> |
150 |
|
|
|
151 |
|
|
</xsl:choose> |
152 |
|
|
|
153 |
|
|
</xsl:copy> |
154 |
|
|
|
155 |
|
|
</xsl:template> |
156 |
|
|
|
157 |
|
|
|
158 |
|
|
|
159 |
|
|
<!-- 2.c. The element manipulators: They mungle a specific element inside the current context. --> |
160 |
|
|
|
161 |
|
|
<!-- copy over node 1:1 (use last element as a template) --> |
162 |
|
|
<xsl:template name="clone_last_element"> |
163 |
|
|
<xsl:copy-of select="*[last()]" /> |
164 |
|
|
</xsl:template> |
165 |
|
|
|
166 |
|
|
<xsl:template name="clone_element_nr"> |
167 |
|
|
<!-- TODO: let idx be passed in via "with-param" or s.th.l.th. --> |
168 |
|
|
<xsl:copy-of select="*[2]" /> |
169 |
|
|
</xsl:template> |
170 |
|
|
|
171 |
|
|
<!-- creates instance of new element --> |
172 |
|
|
<xsl:template name="create_fresh_element"> |
173 |
|
|
<xsl:element name="new">content</xsl:element> |
174 |
|
|
</xsl:template> |
175 |
|
|
|
176 |
|
|
<xsl:template name="xupdate_element_create_embedded"> |
177 |
|
|
<xsl:variable name="huhu" select="*[0]/@key">haha</xsl:variable> |
178 |
|
|
<!-- <xsl:transform version="1.1" xmlns:xupdate="http://www.xmldb.org/xupdate"> --> |
179 |
|
|
<!-- <xupdate:modifications version="1.0" xmlns:xupdate="http://www.xmldb.org/xupdate"> --> |
180 |
|
|
<!-- <xsl:append select="/addresses" child="last()"> --> |
181 |
|
|
<xsl:element name="address"> |
182 |
|
|
<town>San Francisco</town> |
183 |
|
|
</xsl:element> |
184 |
|
|
<xsl:value-of select="*[0]/@key" /> |
185 |
|
|
<xsl:value-of select="$huhu" /> |
186 |
|
|
<!-- </xupdate:modifications> --> |
187 |
|
|
<!-- </xsl:append> --> |
188 |
|
|
<!-- </xsl:transform> --> |
189 |
|
|
</xsl:template> |
190 |
|
|
|
191 |
|
|
|
192 |
|
|
<!-- inject other stuff --> |
193 |
|
|
<xsl:template name="inject_template"> |
194 |
|
|
<xsl:comment> Hello World! </xsl:comment> |
195 |
|
|
|
196 |
|
|
</xsl:template> |
197 |
|
|
|
198 |
|
|
|
199 |
|
|
|
200 |
|
|
|
201 |
|
|
<!-- 0. The root node dispatcher. --> |
202 |
|
|
<!-- <xsl:template match="source"><xsl:call-template name="insertChildNode"/></xsl:template> --> |
203 |
|
|
|
204 |
|
|
<!-- 2. This is the manipulation logic: insertChildNode --> |
205 |
|
|
|
206 |
|
|
<!-- 2.a. The "API" method. - now deprecated --> |
207 |
|
|
<xsl:template name="insertChildNode"> |
208 |
|
|
|
209 |
|
|
<!-- manipulate node --> |
210 |
|
|
<xsl:comment> node - begin </xsl:comment> |
211 |
|
|
|
212 |
|
|
<!-- <xsl:copy-of select="source" /> --> |
213 |
|
|
<xsl:copy> |
214 |
|
|
|
215 |
|
|
<!-- Pass through children 1:1. --> |
216 |
|
|
<xsl:apply-templates /> |
217 |
|
|
|
218 |
|
|
<!-- Call one of the manipulators - this implements injection behavior. --> |
219 |
|
|
<xsl:call-template name="clone_last_element" /> |
220 |
|
|
<xsl:call-template name="inject_template" /> |
221 |
|
|
|
222 |
|
|
</xsl:copy> |
223 |
|
|
<xsl:comment> node - end </xsl:comment> |
224 |
|
|
|
225 |
|
|
</xsl:template> |
226 |
|
|
|
227 |
|
|
|
228 |
|
|
</xsl:stylesheet> |