Project

Profile

Help

How to connect?
Download (17.6 KB) Statistics
| Branch: | Tag: | Revision:

he / latest8.9 / bn / csource / api / Saxon.Api / Destination.cs @ 462aae92

1
using System;
2
using System.IO;
3
using System.Xml;
4
using System.Collections;
5
using JConfiguration = net.sf.saxon.Configuration;
6
using JReceiver = net.sf.saxon.@event.Receiver;
7
using JProperties = java.util.Properties;
8
using JOutputStream = java.io.OutputStream;
9
using JWriter = java.io.Writer;
10
using JFileOutputStream = java.io.FileOutputStream;
11
using JDynamicError = net.sf.saxon.trans.DynamicError;
12
using JResult = javax.xml.transform.Result;
13
using JStreamResult = javax.xml.transform.stream.StreamResult;
14
using JTinyBuilder = net.sf.saxon.tinytree.TinyBuilder;
15
using net.sf.saxon.@event;
16
using net.sf.saxon.om;
17
using net.sf.saxon.value;
18
using net.sf.saxon.query;
19
using net.sf.saxon.dotnet;
20

    
21

    
22
namespace Saxon.Api {
23

    
24

    
25

    
26
    /// <summary>
27
    /// An abstract destination for the results of a query or transformation
28
    /// </summary>
29
    /// <remarks>
30
    /// <para>Note to implementors: To implement a new kind of destination, you need
31
    /// to supply a method <c>getResult</c> which returns an implementation of
32
    /// the JAXP <c>Result</c> interface. Optionally, if the destination
33
    /// performs serialization, you can also implement <c>getOutputProperties</c>,
34
    /// which returns the properties used for serialization.
35
    /// </para>
36
    /// </remarks>
37

    
38

    
39
    public abstract class XmlDestination {
40

    
41
        /// <summary>
42
        /// Get a <c>Result</c> to which the XML document can be sent as a series
43
        /// of events.
44
        /// </summary>
45
        /// <remarks>
46
        /// This must be an implementation of the JAXP <c>Result</c> interface that is
47
        /// recognized by Saxon.
48
        /// </remarks>
49

    
50
        public abstract JResult GetResult();
51

    
52
        /// <summary>
53
        /// Get a set of <c>Properties</c> representing the parameters to the serializer.
54
        /// The default implementation returns an empty set of properties.
55
        /// </summary>
56

    
57
        public virtual JProperties GetOutputProperties() {
58
            return new JProperties();
59
        }
60

    
61
        /// <summary>
62
        /// Close the Destination, releasing any resources that need to be released.
63
        /// </summary>
64
        /// <remarks>
65
        /// This method is called by the system on completion of a query or transformation.
66
        /// Some kinds of Destination may need to close an output stream, others might
67
        /// not need to do anything. The default implementation does nothing.
68
        /// </remarks>
69

    
70
        public virtual void Close() {
71
        }
72

    
73

    
74
    }
75

    
76
    /// <summary>
77
    /// A <c>Serializer</c> takes a tree representation of XML and turns
78
    /// it into lexical XML markup.
79
    /// </summary>
80
    /// <remarks>
81
    /// Note that this is serialization in the sense of the W3C XSLT and XQuery specifications.
82
    /// Unlike the class <c>System.Xml.Serialization.XmlSerializer</c>, this object does not
83
    /// serialize arbitrary CLI objects.
84
    /// </remarks>
85

    
86
    public class Serializer : XmlDestination {
87

    
88
        private JProperties props = new JProperties();
89
        private JOutputStream outputStream = null;
90
        private JWriter writer = null;
91
        private bool mustClose = true;
92

    
93

    
94
        /// <summary>QName identifying the serialization parameter "method". If the method
95
        /// is a user-defined method, then it is given as a QName in Clark notation, that is
96
        /// "{uri}local".</summary>
97

    
98
        public static readonly QName METHOD =
99
            new QName("", "method");
100

    
101
        /// <summary>QName identifying the serialization parameter "byte-order-mark"</summary>
102

    
103
        public static readonly QName BYTE_ORDER_MARK =
104
            new QName("", "byte-order-mark");
105

    
106
        /// <summary>QName identifying the serialization parameter "cdata-section-elements".
107
        /// The value of this parameter is given as a space-separated list of expanded QNames in
108
        /// Clark notation, that is "{uri}local".</summary>
109

    
110
        public static readonly QName CDATA_SECTION_ELEMENTS =
111
            new QName("", "cdata-section-elements");
112

    
113
        /// <summary>QName identifying the serialization parameter "doctype-public"</summary>
114

    
115
        public static readonly QName DOCTYPE_PUBLIC =
116
            new QName("", "doctype-public");
117

    
118
        /// <summary>QName identifying the serialization parameter "doctype-system"</summary>
119

    
120
        public static readonly QName DOCTYPE_SYSTEM =
121
            new QName("", "doctype-system");
122

    
123
        /// <summary>QName identifying the serialization parameter "encoding"</summary>
124

    
125
        public static readonly QName ENCODING =
126
            new QName("", "encoding");
127

    
128
        /// <summary>QName identifying the serialization parameter "escape-uri-attributes".
129
        /// The value is the string "yes" or "no".</summary>
130

    
131
        public static readonly QName ESCAPE_URI_ATTRIBUTES =
132
            new QName("", "escape-uri-attributes");
133

    
134
        /// <summary>QName identifying the serialization parameter "include-content-type".
135
        /// The value is the string "yes" or "no".</summary>
136

    
137
        public static readonly QName INCLUDE_CONTENT_TYPE =
138
            new QName("", "include-content-type");
139

    
140
        /// <summary>QName identifying the serialization parameter "indent".
141
        /// The value is the string "yes" or "no".</summary>
142

    
143
        public static readonly QName INDENT =
144
            new QName("", "indent");
145

    
146
        /// <summary>QName identifying the serialization parameter "media-type".</summary>
147

    
148
        public static readonly QName MEDIA_TYPE =
149
            new QName("", "media-type");
150

    
151
        /// <summary>QName identifying the serialization parameter "normalization-form"</summary>
152

    
153
        public static readonly QName NORMALIZATION_FORM =
154
            new QName("", "normalization-form");
155

    
156
        /// <summary>QName identifying the serialization parameter "omit-xml-declaration".
157
        /// The value is the string "yes" or "no".</summary>
158

    
159
        public static readonly QName OMIT_XML_DECLARATION =
160
            new QName("", "omit-xml-declaration");
161

    
162
        /// <summary>QName identifying the serialization parameter "standalone".
163
        /// The value is the string "yes" or "no" or "omit".</summary>
164

    
165
        public static readonly QName STANDALONE =
166
            new QName("", "standalone");
167

    
168
        /// <summary>QName identifying the serialization parameter "undeclare-prefixes".
169
        /// The value is the string "yes" or "no".</summary>
170

    
171
        public static readonly QName UNDECLARE_PREFIXES =
172
            new QName("", "undeclare-prefixes");
173

    
174
        /// <summary>QName identifying the serialization parameter "use-character-maps".
175
        /// This is available only with XSLT. The value of the parameter is a list of expanded QNames
176
        /// in Clark notation giving the names of character maps defined in the XSLT stylesheet.</summary>
177

    
178
        public static readonly QName USE_CHARACTER_MAPS =
179
            new QName("", "use-character-maps");
180

    
181
        /// <summary>QName identifying the serialization parameter "version"</summary>
182

    
183
        public static readonly QName VERSION =
184
            new QName("", "version");
185

    
186
        private const String SAXON = NamespaceConstant.SAXON;
187

    
188

    
189
        /// <summary>QName identifying the serialization parameter "saxon:character-representation"</summary>
190

    
191

    
192
        public static readonly QName SAXON_CHARACTER_REPRESENTATION =
193
            new QName(SAXON, "saxon:character-representation");
194

    
195
        /// <summary>QName identifying the serialization parameter "saxon:indent-spaces". The value
196
        /// is an integer (represented as a string) indicating the amount of indentation required.
197
        /// If specified, this parameter overrides indent="no".</summary>
198

    
199
        public static readonly QName SAXON_INDENT_SPACES =
200
            new QName(SAXON, "saxon:indent-spaces");
201

    
202
        /// <summary>QName identifying the serialization parameter "saxon:next-in-chain". This
203
        /// is available only with XSLT, and identifies the URI of a stylesheet that is to be used to
204
        /// process the results before passing them to their final destination.</summary>
205

    
206
        public static readonly QName NEXT_IN_CHAIN =
207
            new QName(SAXON, "saxon:next-in-chain");
208

    
209
        /// <summary>QName identifying the serialization parameter "require-well-formed". The
210
        /// value is the string "yes" or "no". If set to "yes", the output must be a well-formed
211
        /// document, or an error will be reported.</summary>
212

    
213
        public static readonly QName SAXON_REQUIRE_WELL_FORMED =
214
            new QName(SAXON, "saxon:require-well-formed");
215

    
216

    
217
        /// <summary>Create a Serializer</summary>
218

    
219
        public Serializer() {
220
        }
221

    
222
        /// <summary>Set a serialization property</summary>
223
        /// <remarks>In the case of XSLT, properties set within the serializer override
224
        /// any properties set in <c>xsl:output</c> declarations in the stylesheet.
225
        /// Similarly, with XQuery, they override any properties set in the Query
226
        /// prolog using <c>declare option saxon:output</c>.</remarks>
227
        /// <example>
228
        ///   <code>
229
        ///     Serializer qout = new Serializer();
230
        ///     qout.SetOutputProperty(Serializer.METHOD, "xml");
231
        ///     qout.SetOutputProperty(Serializer.INDENT, "yes");
232
        ///     qout.SetOutputProperty(Serializer.SAXON_INDENT_SPACES, "1");
233
        ///   </code>
234
        /// </example> 
235
        /// <param name="name">The name of the serialization property to be set</param>
236
        /// <param name="value">The value to be set for the serialization property. May be null
237
        /// to unset the property (that is, to set it back to the default value).</param>
238

    
239
        public void SetOutputProperty(QName name, String value) {
240
            props.setProperty(name.ClarkName, value);
241
        }
242

    
243
        /// <summary>Specify the destination of the serialized output, in the
244
        /// form of a file name</summary>
245
        /// <param name="filename">The name of the file to receive the serialized output</param>
246
        /// <exception>Throws a <c>DyamicError</c> if it is not possible to create an output
247
        /// stream to write to this file, for example, if the filename is in a directory
248
        /// that does not exist.</exception>
249

    
250
        public void SetOutputFile(String filename) {
251
            try {
252
                outputStream = new JFileOutputStream(filename);
253
                mustClose = true;
254
            } catch (java.io.IOException err) {
255
                JDynamicError e = new JDynamicError(err);
256
                throw new DynamicError(e);
257
            }
258
        }
259

    
260
        /// <summary>Specify the destination of the serialized output, in the
261
        /// form of a <c>Stream</c></summary>
262
        /// <param name="stream">The stream to which the output will be written.
263
        /// This must be a stream that allows writing.</param>
264

    
265
        public void SetOutputStream(Stream stream) {
266
            outputStream = new DotNetOutputStream(stream);
267
            mustClose = false;
268
        }
269

    
270
        /// <summary>Specify the destination of the serialized output, in the
271
        /// form of a <c>TextWriter</c></summary>
272
        /// <remarks>Note that when writing to a <c>TextWriter</c>, character encoding is
273
        /// the responsibility of the <c>TextWriter</c>, not the <c>Serializer</c>. This
274
        /// means that the encoding requested in the output properties is ignored; it also
275
        /// means that characters that cannot be represented in the target encoding will
276
        /// use whatever fallback representation the <c>TextWriter</c> defines, rather than
277
        /// being represented as XML character references.</remarks>
278
        /// <param name="textWriter">The stream to which the output will be written.
279
        /// This must be a stream that allows writing.</param>
280

    
281
        public void SetOutputWriter(TextWriter textWriter) {
282
            writer = new DotNetWriter(textWriter);
283
            mustClose = false;
284
        }
285

    
286
        internal JReceiver GetReceiver(JConfiguration config) {
287
            return config.getSerializerFactory().getReceiver(
288
                    GetResult(),
289
                    config.makePipelineConfiguration(),
290
                    GetOutputProperties());
291

    
292
        }
293

    
294

    
295
        /// <summary inherit="yes"/>
296

    
297
        public override JResult GetResult() {
298
            if (outputStream != null) {
299
                return new JStreamResult(outputStream);
300
            } else if (writer != null) {
301
                return new JStreamResult(writer);
302
            } else {
303
                return new JStreamResult(new DotNetWriter(Console.Out));
304
            }
305
        }
306

    
307
        /// <summary inherit="yes"/>
308

    
309
        public override JProperties GetOutputProperties() {
310
            return props;
311
        }
312

    
313
        /// <summary inherit="yes"/>
314

    
315
        public override void Close() {
316
            if (mustClose) {
317
                if (outputStream != null) {
318
                    outputStream.close();
319
                }
320
                if (writer != null) {
321
                    writer.close();
322
                }
323
            }
324
        }
325
    }
326

    
327
    /// <summary>
328
    /// A <c>DomDestination</c> represents an XmlDocument that is constructed to hold the
329
    /// output of a query or transformation.
330
    /// </summary>
331
    /// <remarks>
332
    /// No data needs to be supplied to the DomDestination object. The query or transformation
333
    /// populates an XmlDocument, which may then be retrieved as the value of the <c>XmlDocument</c>
334
    /// property
335
    /// </remarks>
336

    
337
    public class DomDestination : XmlDestination {
338

    
339
        internal DotNetDomBuilder builder;
340

    
341
        /// <summary>Construct a DomDestination</summary>
342

    
343
        public DomDestination() {
344
            builder = new DotNetDomBuilder();
345
        }
346

    
347
        /// <summary>After construction, retrieve the constructed document node</summary>
348

    
349
        public XmlDocument XmlDocument {
350
            get { return builder.getDocumentNode(); }
351
        }
352

    
353
        /// <summary inherit="yes"/>
354

    
355
        public override JResult GetResult() {
356
            return builder;
357
        }
358
    }
359

    
360
    /// <summary>
361
    /// A <c>TextWriterDestination</c> is an implementation of <c>XmlDestination</c> that wraps
362
    /// an instance of <c>XmlTextWriter</c>.
363
    /// </summary>
364
    /// <remarks>
365
    /// Note that when a <c>TextWriterDestination</c> is used to process the output of a stylesheet
366
    /// or query, the output format depends only on the way the underlying <c>TextWriter</c>
367
    /// is configured; serialization parameters present in the stylesheet or query are ignored.
368
    /// </remarks>
369

    
370
    public class TextWriterDestination : XmlDestination {
371

    
372
        internal XmlTextWriter writer;
373

    
374
        /// <summary>Construct a TextWriterDestination</summary>
375
        /// <param name="writer">The <c>XmlTextWriter</c> that is to be notified of the events
376
        /// representing the XML document.</param>
377

    
378
        public TextWriterDestination(XmlTextWriter writer) {
379
            this.writer = writer;
380
        }
381

    
382
        /// <summary inherit="yes"/>
383

    
384
        public override JResult GetResult() {
385
            DotNetReceiver dnr = new DotNetReceiver(writer);
386
            return dnr;
387
            //net.sf.saxon.@event.TracingFilter filter = new net.sf.saxon.@event.TracingFilter();
388
            //filter.setUnderlyingReceiver(dnr);
389
            //return filter;
390
        }
391
    }
392

    
393

    
394
    /// <summary>
395
    /// An <c>XdmDestination</c> represents an XdmNode that is constructed to hold the
396
    /// output of a query or transformation: that is, a tree using Saxon's implementation of the
397
    /// XDM data model
398
    /// </summary>
399
    /// <remarks>
400
    /// <para>No data needs to be supplied to the XdmDestination object. The query or transformation
401
    /// populates an XmlNode, which may then be retrieved as the value of the <c>XmlNode</c>
402
    /// property.</para>
403
    /// <para>An XdmDestination can be reused to hold the results of a second transformation only
404
    /// if the <c>reset</c> method is first called to reset its state.</para>
405
    /// </remarks>
406

    
407
    public class XdmDestination : XmlDestination {
408

    
409
        internal JTinyBuilder builder;
410

    
411
        /// <summary>Construct a DomDestination</summary>
412

    
413
        public XdmDestination() {
414
            builder = new JTinyBuilder();
415
        }
416

    
417
        /// <summary>Reset the state of the XdmDestination so that it can be used to hold
418
        /// the result of another transformation.</summary>
419

    
420
        public void Reset() {
421
            builder = new JTinyBuilder();
422
        }
423

    
424
        /// <summary>After construction, retrieve the constructed document node</summary>
425

    
426
        public XdmNode XdmNode {
427
            get {
428
                return (XdmNode)XdmValue.Wrap(builder.getCurrentRoot());
429
            }
430
        }
431

    
432
        /// <summary inherit="yes"/>
433

    
434
        public override JResult GetResult() {
435
            return builder;
436
        }
437
    }
438

    
439

    
440
}
441

    
442
//
443
// The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
444
// you may not use this file except in compliance with the License. You may obtain a copy of the
445
// License at http://www.mozilla.org/MPL/
446
//
447
// Software distributed under the License is distributed on an "AS IS" basis,
448
// WITHOUT WARRANTY OF ANY KIND, either express or implied.
449
// See the License for the specific language governing rights and limitations under the License.
450
//
451
// The Original Code is: all this file.
452
//
453
// The Initial Developer of the Original Code is Michael H. Kay.
454
//
455
// Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
456
//
457
// Contributor(s): none.
458
//
(2-2/8)