Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HeuristicLab.Problems.GrammaticalOptimization/SharpVectorModel/DocumentStructure/SvgDocument.cs @ 14040

Last change on this file since 14040 was 12762, checked in by aballeit, 9 years ago

#2283 GUI updates, Tree-chart, MCTS Version 2 (prune leaves)

File size: 34.2 KB
Line 
1// Define this to enable the dispatching of load events.  The implementation
2// of load events requires that a complete implementation of SvgDocument.Load
3// be supplied rather than relying on the base XmlDocument.Load behaviour.
4// This is required because I know of no way to hook into the key stages of
5// XML document creation in order to throw events at the right times during
6// the load process.
7// <developer>niklas@protocol7.com</developer>
8// <completed>60</completed>
9
10using System;
11using System.Xml;
12using System.Xml.Schema;
13using System.IO;
14using System.IO.Compression;
15using System.Collections.Generic;
16using System.Text.RegularExpressions;
17
18using SharpVectors.Xml;
19using SharpVectors.Dom.Css;
20using SharpVectors.Dom.Resources;
21
22namespace SharpVectors.Dom.Svg
23{
24    /// <summary>
25    /// The root object in the document object hierarchy of an Svg document.
26    /// </summary>
27    /// <remarks>
28    /// <p>
29    /// When an 'svg'  element is embedded inline as a component of a
30    /// document from another namespace, such as when an 'svg' element is
31    /// embedded inline within an XHTML document
32    /// [<a href="http://www.w3.org/TR/SVG/refs.html#ref-XHTML">XHTML</a>],
33    /// then an
34    /// <see cref="ISvgDocument">ISvgDocument</see> object will not exist;
35    /// instead, the root object in the
36    /// document object hierarchy will be a Document object of a different
37    /// type, such as an HTMLDocument object.
38    /// </p>
39    /// <p>
40    /// However, an <see cref="ISvgDocument">ISvgDocument</see> object will
41    /// indeed exist when the root
42    /// element of the XML document hierarchy is an 'svg' element, such as
43    /// when viewing a stand-alone SVG file (i.e., a file with MIME type
44    /// "image/svg+xml"). In this case, the
45    /// <see cref="ISvgDocument">ISvgDocument</see> object will be the
46    /// root object of the document object model hierarchy.
47    /// </p>
48    /// <p>
49    /// In the case where an SVG document is embedded by reference, such as
50    /// when an XHTML document has an 'object' element whose href attribute
51    /// references an SVG document (i.e., a document whose MIME type is
52    /// "image/svg+xml" and whose root element is thus an 'svg' element),
53    /// there will exist two distinct DOM hierarchies. The first DOM hierarchy
54    /// will be for the referencing document (e.g., an XHTML document). The
55    /// second DOM hierarchy will be for the referenced SVG document. In this
56    /// second DOM hierarchy, the root object of the document object model
57    /// hierarchy is an <see cref="ISvgDocument">ISvgDocument</see> object.
58    /// </p>
59    /// <p>
60    /// The <see cref="ISvgDocument">ISvgDocument</see> interface contains a
61    /// similar list of attributes and
62    /// methods to the HTMLDocument interface described in the
63    /// <a href="http://www.w3.org/TR/REC-DOM-Level-1/level-one-html.html">Document
64    /// Object Model (HTML) Level 1</a> chapter of the
65    /// [<a href="http://www.w3.org/TR/SVG/refs.html#ref-DOM1">DOM1</a>] specification.
66    /// </p>
67    /// </remarks>
68    public class SvgDocument : CssXmlDocument, ISvgDocument
69    {
70        #region Public Static Fields
71
72        public const string SvgNamespace   = "http://www.w3.org/2000/svg";
73
74        public const string XLinkNamespace = "http://www.w3.org/1999/xlink";
75
76        #endregion
77
78        #region Private Fields
79       
80        private bool _ignoreComments;
81        private bool _ignoreProcessingInstructions;
82        private bool _ignoreWhitespace;
83
84        private SvgWindow _window;
85
86        private XmlReaderSettings _settings;
87
88        #endregion
89
90        #region Constructors
91
92        private SvgDocument()
93        {
94            _ignoreComments               = false;
95            _ignoreWhitespace             = false;
96            _ignoreProcessingInstructions = false;
97
98            this.PreserveWhitespace = true;
99        }
100
101        public SvgDocument(SvgWindow window)
102            : this()
103        {
104            this._window = window;
105            this._window.Document = this;
106
107            // set up CSS properties
108            AddStyleElement(SvgDocument.SvgNamespace, "style");
109            CssPropertyProfile = CssPropertyProfile.SvgProfile;
110        }
111
112        #endregion
113
114        #region Public Events
115
116        /// <summary>
117        /// Namespace resolution event delegate.
118        /// </summary>
119        public delegate void ResolveNamespaceDelegate(object sender, SvgResolveNamespaceEventArgs e);
120        /// <summary>
121        /// URI resolution event delegate
122        /// </summary>
123        public delegate void ResolveUriDelegate(object sender, SvgResolveUriEventArgs e);
124
125        /// <summary>
126        /// Occurs when a namespace is being resolved.
127        /// </summary>
128        public event ResolveNamespaceDelegate ResolveNamespace;
129
130        /// <summary>
131        /// Occurs when an URI is resolved (always).
132        /// </summary>
133        public event ResolveUriDelegate ResolvingUri;
134
135        #endregion
136
137        #region Public Properties
138
139        public XmlReaderSettings CustomSettings
140        {
141            get
142            {
143                return _settings;
144            }
145            set
146            {
147                _settings = value;
148            }
149        }
150
151        #endregion
152
153        #region NamespaceManager
154
155        private XmlNamespaceManager namespaceManager;
156
157        public XmlNamespaceManager NamespaceManager
158        {
159            get
160            {
161                if (namespaceManager == null)
162                {
163                    // Setup namespace manager and add default namespaces
164                    namespaceManager = new XmlNamespaceManager(this.NameTable);
165                    namespaceManager.AddNamespace(String.Empty, SvgDocument.SvgNamespace);
166                    namespaceManager.AddNamespace("svg", SvgDocument.SvgNamespace);
167                    namespaceManager.AddNamespace("xlink", SvgDocument.XLinkNamespace);
168                }
169
170                return namespaceManager;
171            }
172        }
173
174        #endregion
175
176        #region Type handling and creation of elements
177
178        public override XmlElement CreateElement(string prefix, string localName, string ns)
179        {
180            XmlElement result = SvgElementFactory.Create(prefix, localName, ns, this);
181            if (result != null)
182            {
183                return result;
184            }
185            else if (ns == SvgNamespace)
186            {
187                return new SvgElement(prefix, localName, ns, this);
188            }
189            else
190            {
191                // Now, if the ns is empty, we try creating with the default namespace for cases
192                // where the node is imported from an external SVG document...
193                if (String.IsNullOrEmpty(ns))
194                {
195                    result = SvgElementFactory.Create(prefix, localName, SvgNamespace, this);
196                    if (result != null)
197                    {       
198                        return result;
199                    }
200                }
201            }
202
203            return base.CreateElement(prefix, localName, ns);
204        }
205
206        #endregion
207
208        #region Support collections
209
210        private string[] supportedFeatures = new string[]
211      {
212        "org.w3c.svg.static",
213        "http://www.w3.org/TR/Svg11/feature#Shape",
214        "http://www.w3.org/TR/Svg11/feature#BasicText",
215        "http://www.w3.org/TR/Svg11/feature#OpacityAttribute"
216      };
217
218        private string[] supportedExtensions = new string[] { };
219
220        public override bool Supports(string feature, string version)
221        {
222            foreach (string supportedFeature in supportedFeatures)
223            {
224                if (supportedFeature == feature)
225                {
226                    return true;
227                }
228            }
229
230            foreach (string supportedExtension in supportedExtensions)
231            {
232                if (supportedExtension == feature)
233                {
234                    return true;
235                }
236            }
237
238            return base.Supports(feature, version);
239        }
240
241        #endregion
242
243        #region Overrides of Load
244
245        private XmlReaderSettings GetXmlReaderSettings()
246        {
247            if (_settings != null)
248            {
249                return _settings;
250            }
251            DynamicXmlUrlResolver xmlResolver = new DynamicXmlUrlResolver();
252            xmlResolver.Resolving     += OnXmlResolverResolving;
253            xmlResolver.GettingEntity += OnXmlResolverGettingEntity;
254
255            XmlReaderSettings settings = new XmlReaderSettings();
256
257            settings.ProhibitDtd                  = false;
258
259            settings.IgnoreComments               = _ignoreComments;
260            settings.IgnoreWhitespace             = _ignoreWhitespace;
261            settings.IgnoreProcessingInstructions = _ignoreProcessingInstructions;
262            settings.XmlResolver                  = xmlResolver;
263
264            return settings;
265        }
266
267        //private void PrepareXmlResolver(XmlReaderSettings settings)
268        //{   
269        //    /*// TODO: 1.2 has removed the DTD, can we do this safely?
270        //    if (reader != null && reader is XmlValidatingReader)
271        //    {
272        //        XmlValidatingReader valReader = (XmlValidatingReader)reader;
273        //        valReader.ValidationType = ValidationType.None;
274        //    }
275        //    return;
276
277        //    LocalDtdXmlUrlResolver localDtdXmlUrlResolver = new LocalDtdXmlUrlResolver();
278        //    localDtdXmlUrlResolver.AddDtd("http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd", @"dtd\svg10.dtd");
279        //          localDtdXmlUrlResolver.AddDtd("http://www.w3.org/TR/SVG/DTD/svg10.dtd", @"dtd\svg10.dtd");
280        //          localDtdXmlUrlResolver.AddDtd("http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-tiny.dtd", @"dtd\svg11-tiny.dtd");
281        //          localDtdXmlUrlResolver.AddDtd("http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-basic.dtd", @"dtd\svg11-basic.dtd");
282        //          localDtdXmlUrlResolver.AddDtd("http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd", @"dtd\svg11.dtd");
283     
284        //          if (reader != null && reader is XmlValidatingReader)
285        //          {
286        //              XmlValidatingReader valReader = (XmlValidatingReader)reader;
287       
288        //              valReader.ValidationType = ValidationType.None;
289        //              valReader.XmlResolver = localDtdXmlUrlResolver;
290        //          }
291     
292        //          this.XmlResolver = localDtdXmlUrlResolver;*/
293
294        //    //LocalDtdXmlUrlResolver localDtdXmlUrlResolver = new LocalDtdXmlUrlResolver();
295        //    //localDtdXmlUrlResolver.AddDtd("http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd", @"dtd\svg10.dtd");
296        //    //localDtdXmlUrlResolver.AddDtd("http://www.w3.org/TR/SVG/DTD/svg10.dtd", @"dtd\svg10.dtd");
297        //    //localDtdXmlUrlResolver.AddDtd("http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-tiny.dtd", @"dtd\svg11-tiny.dtd");
298        //    //localDtdXmlUrlResolver.AddDtd("http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-basic.dtd", @"dtd\svg11-basic.dtd");
299        //    //localDtdXmlUrlResolver.AddDtd("http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd", @"dtd\svg11.dtd");
300
301        //    //string currentDir = Path.GetDirectoryName(
302        //    //    System.Reflection.Assembly.GetExecutingAssembly().Location);
303        //    //string localDtd = Path.Combine(currentDir, "dtd");
304        //    //if (Directory.Exists(localDtd))
305        //    //{
306        //    //    LocalDtdXmlUrlResolver localDtdXmlUrlResolver = new LocalDtdXmlUrlResolver();
307        //    //    localDtdXmlUrlResolver.AddDtd("http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd", Path.Combine(localDtd, "svg10.dtd"));
308        //    //    localDtdXmlUrlResolver.AddDtd("http://www.w3.org/TR/SVG/DTD/svg10.dtd", Path.Combine(localDtd, "svg10.dtd"));
309        //    //    localDtdXmlUrlResolver.AddDtd("http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-tiny.dtd", Path.Combine(localDtd, "svg11-tiny.dtd"));
310        //    //    localDtdXmlUrlResolver.AddDtd("http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-basic.dtd", Path.Combine(localDtd, "svg11-basic.dtd"));
311        //    //    localDtdXmlUrlResolver.AddDtd("http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd", Path.Combine(localDtd, "svg11.dtd"));
312
313        //    //    settings.XmlResolver = localDtdXmlUrlResolver;     
314        //    //}
315        //    //else
316        //    //{
317        //    //    settings.XmlResolver = null;     
318        //    //}
319        //}
320
321        /// <overloads>
322        /// Loads an XML document.Loads the specified XML data.
323        /// <blockquote>
324        /// <b>Note</b>   The Load method always preserves significant white
325        /// space. The PreserveWhitespace property determines whether or not
326        /// white space is preserved. The default is false, whites space is
327        /// not preserved.
328        /// </blockquote>
329        /// </overloads>
330        /// <summary>
331        /// Loads the XML document from the specified URL.
332        /// </summary>
333        /// <param name="url">
334        /// URL for the file containing the XML document to load.
335        /// </param>
336        public override void Load(string url)
337        {
338            // Provide a support for the .svgz files...
339            UriBuilder fileUrl = new UriBuilder(url);
340            if (String.Equals(fileUrl.Scheme, "file"))
341            {
342                string fileExt = Path.GetExtension(url);
343                if (String.Equals(fileExt, ".svgz", StringComparison.OrdinalIgnoreCase))
344                {
345                    using (FileStream fileStream = File.OpenRead(fileUrl.Uri.LocalPath))
346                    {
347                        using (GZipStream zipStream =
348                            new GZipStream(fileStream, CompressionMode.Decompress))
349                        {
350                            this.Load(zipStream);
351                        }
352                    }
353
354                    return;
355                }
356            }
357
358            //XmlReaderSettings settings = this.GetXmlReaderSettings();
359
360            //PrepareXmlResolver(settings);
361            //using (XmlReader reader = XmlReader.Create(url, settings))
362            using (XmlReader reader = CreateValidatingXmlReader(url))
363            {
364                this.Load(reader);
365            }
366        }
367
368        /// <summary>
369        /// Loads the XML document from the specified stream but with the
370        /// specified base URL
371        /// </summary>
372        /// <param name="baseUrl">
373        /// Base URL for the stream from which the XML document is loaded.
374        /// </param>
375        /// <param name="stream">
376        /// The stream containing the XML document to load.
377        /// </param>
378        public void Load(string baseUrl, Stream stream)
379        {
380            //XmlReaderSettings settings = this.GetXmlReaderSettings();
381
382            //PrepareXmlResolver(settings);
383            //using (XmlReader reader = XmlReader.Create(stream, settings, baseUrl))
384            using (XmlReader reader = CreateValidatingXmlReader(baseUrl, stream))
385            {
386                this.Load(reader);                                   
387            }
388        }
389
390        /// <summary>
391        /// Loads the XML document from the specified
392        /// <see cref="TextReader">TextReader</see>.
393        /// </summary>
394        /// <param name="reader"></param>
395        public override void Load(TextReader reader)
396        {
397            //XmlReaderSettings settings = this.GetXmlReaderSettings();
398
399            //PrepareXmlResolver(settings);
400            //using (XmlReader xmlReader = XmlReader.Create(reader, settings))
401            using (XmlReader xmlReader = CreateValidatingXmlReader(reader))
402            {
403                this.Load(xmlReader);
404            }
405        }
406
407        /// <summary>
408        /// Loads the XML document from the specified stream.
409        /// </summary>
410        /// <param name="stream">
411        /// The stream containing the XML document to load.
412        /// </param>
413        public override void Load(Stream stream)
414        {
415            //XmlReaderSettings settings = this.GetXmlReaderSettings();
416
417            //PrepareXmlResolver(settings);
418            //using (XmlReader reader = XmlReader.Create(stream, settings))
419            using (XmlReader reader = CreateValidatingXmlReader(String.Empty, stream))
420            {
421                this.Load(reader);
422            }
423        }
424
425        #endregion
426
427        #region Resource handling
428
429        /// <summary>
430        /// Entities URIs corrections are cached here.
431        /// Currently consists in mapping '_' to '' (nothing)
432        /// </summary>
433        private static IDictionary<string, string> _entitiesUris;
434
435        /// <summary>
436        /// Semaphore to access _entitiesUris
437        /// </summary>
438        private static readonly object _entitiesUrisLock = new object();
439
440        /// <summary>
441        /// Root where resources are embedded
442        /// </summary>
443        private static readonly Type _rootType = typeof(Root);
444
445        /// <summary>
446        /// Given a transformed resource name, find a possible existing resource.
447        /// </summary>
448        /// <param name="uri">The URI.</param>
449        /// <returns></returns>
450        private static string GetEntityUri(string uri)
451        {
452            lock (_entitiesUrisLock)
453            {
454                if (_entitiesUris == null)
455                {
456                    _entitiesUris = new Dictionary<string, string>();
457                    string[] names = _rootType.Assembly.GetManifestResourceNames();
458                    foreach (string name in names)
459                    {
460                        if (name.StartsWith(_rootType.Namespace))
461                        {
462                            string namePart = name.Substring(_rootType.Namespace.Length + 1); // the +1 is for the "."
463                            _entitiesUris[namePart] = name;
464                            _entitiesUris[namePart.Replace("_", "")] = name;
465                        }
466                    }
467                }
468                string entityUri;
469                _entitiesUris.TryGetValue(uri, out entityUri);
470                return entityUri;
471            }
472        }
473
474        /// <summary>
475        /// Handles DynamicXmlUrlResolver GettingEntity event.
476        /// </summary>
477        /// <param name="absoluteUri">The absolute URI.</param>
478        /// <param name="role">The role.</param>
479        /// <param name="ofObjectToReturn">The of object to return.</param>
480        /// <returns></returns>
481        private object OnXmlResolverGettingEntity(Uri absoluteUri, string role, Type ofObjectToReturn)
482        {
483            if (absoluteUri.IsFile)
484            {
485                string fullPath = absoluteUri.ToString();
486                if (!String.IsNullOrEmpty(fullPath))
487                {
488                    fullPath = fullPath.Replace('\\', '/');
489
490                    if (fullPath.EndsWith("-//W3C//DTD SVG 1.1 Basic//EN", StringComparison.OrdinalIgnoreCase) ||
491                        fullPath.EndsWith("-/W3C/DTD SVG 1.1 Basic/EN", StringComparison.OrdinalIgnoreCase))
492                    {
493                        string resourceUri = GetEntityUri("www.w3.org.Graphics.SVG.1.1.DTD.svg11-basic.dtd");
494                        if (resourceUri != null)
495                            return GetEntityFromUri(resourceUri, ofObjectToReturn);
496                    }                           
497                    else if (fullPath.EndsWith("-//W3C//DTD SVG 1.1//EN", StringComparison.OrdinalIgnoreCase) ||
498                        fullPath.EndsWith("-/W3C/DTD SVG 1.1/EN", StringComparison.OrdinalIgnoreCase))
499                    {
500                        string resourceUri = GetEntityUri("www.w3.org.Graphics.SVG.1.1.DTD.svg11.dtd");
501                        if (resourceUri != null)
502                            return GetEntityFromUri(resourceUri, ofObjectToReturn);
503                    }
504                    else if (fullPath.EndsWith("-//W3C//DTD SVG 1.1 Full//EN", StringComparison.OrdinalIgnoreCase) ||
505                        fullPath.EndsWith("-/W3C/DTD SVG 1.1 Full/EN", StringComparison.OrdinalIgnoreCase))
506                    {
507                        string resourceUri = GetEntityUri("www.w3.org.Graphics.SVG.1.1.DTD.svg11.dtd");
508                        if (resourceUri != null)
509                            return GetEntityFromUri(resourceUri, ofObjectToReturn);
510                    }
511                    else if (fullPath.EndsWith("-//W3C//DTD SVG 1.0//EN", StringComparison.OrdinalIgnoreCase) ||
512                        fullPath.EndsWith("-/W3C/DTD SVG 1.0/EN", StringComparison.OrdinalIgnoreCase))
513                    {
514                        string resourceUri = GetEntityUri("www.w3.org.TR.2001.REC-SVG-20010904.DTD.svg10.dtd");
515                        if (resourceUri != null)
516                            return GetEntityFromUri(resourceUri, ofObjectToReturn);
517                    }
518                    else if (fullPath.EndsWith("-//W3C//DTD SVG 1.1 Tiny//EN", StringComparison.OrdinalIgnoreCase) ||
519                        fullPath.EndsWith("-/W3C/DTD SVG 1.1 Tiny/EN", StringComparison.OrdinalIgnoreCase))
520                    {
521                        string resourceUri = GetEntityUri("www.w3.org.Graphics.SVG.1.1.DTD.svg11-tiny.dtd");
522                        if (resourceUri != null)
523                            return GetEntityFromUri(resourceUri, ofObjectToReturn);
524                    }
525                }                   
526
527                return null;
528            }
529
530            string path = (absoluteUri.Host + absoluteUri.AbsolutePath.Replace('/', '.'));
531            string foundResource = GetEntityUri(path);
532            if (foundResource != null)
533                return GetEntityFromUri(foundResource, ofObjectToReturn);
534
535            return null;
536        }
537
538        /// <summary>
539        /// Gettings the URI direct.
540        /// </summary>
541        /// <param name="path">The path.</param>
542        /// <param name="ofObjectToReturn">The of object to return.</param>
543        /// <returns></returns>
544        private static object GetEntityFromUri(string path, Type ofObjectToReturn)
545        {
546            if (ofObjectToReturn == typeof(Stream))
547            {
548                using (Stream resourceStream = _rootType.Assembly.GetManifestResourceStream(path))
549                {
550                    if (resourceStream != null)
551                    {
552                        // we copy the contents to a MemoryStream because the loader doesn't release original streams,
553                        // resulting in an assembly lock
554                        int resourceLength = (int)resourceStream.Length;
555                        MemoryStream memoryStream = new MemoryStream(resourceLength);
556                        resourceStream.Read(memoryStream.GetBuffer(), 0, resourceLength);
557
558                        return memoryStream;
559                    }
560                }
561            }
562
563            return null;
564        }
565
566        /// <summary>
567        /// Handles DynamicXmlResolver Resolve event.
568        /// </summary>
569        /// <param name="relativeUri">The relative URI.</param>
570        /// <returns></returns>
571        private string OnXmlResolverResolving(string relativeUri)
572        {
573            if (this.ResolvingUri != null)
574            {
575                SvgResolveUriEventArgs e = new SvgResolveUriEventArgs { Uri = relativeUri };
576                ResolvingUri(this, e);
577                relativeUri = e.Uri;
578            }
579            if (relativeUri.Equals("http://www.w3.org/2000/svg", StringComparison.OrdinalIgnoreCase))
580            {
581                relativeUri = "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd";
582            }
583
584            return relativeUri;
585        }
586
587        /// <summary>
588        /// Gets/create an XML parser context, with predefined namespaces
589        /// </summary>
590        /// <returns></returns>
591        private XmlParserContext GetXmlParserContext()
592        {
593            DynamicXmlNamespaceManager xmlNamespaceManager = new DynamicXmlNamespaceManager(new NameTable());
594            xmlNamespaceManager.Resolve += OnResolveXmlNamespaceManager;
595            XmlParserContext xmlParserContext = new XmlParserContext(null,
596                xmlNamespaceManager, null, XmlSpace.None);
597
598            return xmlParserContext;
599        }
600
601        /// <summary>
602        /// Handles DynamicXmlNamespaceManager Resolve event.
603        /// </summary>
604        /// <param name="prefix">The prefix.</param>
605        /// <returns></returns>
606        private string OnResolveXmlNamespaceManager(string prefix)
607        {
608            string uri = null;
609            if (this.ResolveNamespace != null)
610            {
611                SvgResolveNamespaceEventArgs e = new SvgResolveNamespaceEventArgs(prefix);
612                ResolveNamespace(this, e);
613                uri = e.Uri;
614            }
615            if (String.IsNullOrEmpty(uri))
616            {
617                // some defaults added here
618                switch (prefix)
619                {
620                    case "rdf":
621                        uri = "http://www.w3.org/1999/02/22-rdf-syntax-ns#";
622                        break;
623                    case "cc":
624                        uri = "http://web.resource.org/cc";
625                        break;
626                    case "dc":
627                        uri = "http://purl.org/dc/elements/1.1/";
628                        break;
629                    case "rdfs":
630                        uri = "http://www.w3.org/2000/01/rdf-schema#";
631                        break;
632                    case "owl":
633                        uri = "http://www.w3.org/2002/07/owl#";
634                        break;
635                    case "foaf":
636                        uri = "http://xmlns.com/foaf/0.1/";
637                        break;
638                    case "xsd":
639                        uri = "http://www.w3c.org/2001/XMLSchema#";
640                        break;
641                    case "xlink":
642                        uri = "http://www.w3.org/1999/xlink";
643                        break;
644                }
645            }
646            return uri;
647        }
648
649        /// <summary>
650        /// Creates the validating XML reader.
651        /// </summary>
652        /// <param name="uri">The URI.</param>
653        /// <returns></returns>
654        private XmlReader CreateValidatingXmlReader(string uri)
655        {
656            XmlReaderSettings xmlReaderSettings = GetXmlReaderSettings();
657            XmlParserContext xmlParserContext   = GetXmlParserContext();
658            return XmlReader.Create(uri, xmlReaderSettings, xmlParserContext);
659        }
660
661        /// <summary>
662        /// Creates the validating XML reader.
663        /// </summary>
664        /// <param name="textReader">The text reader.</param>
665        /// <returns></returns>
666        private XmlReader CreateValidatingXmlReader(TextReader textReader)
667        {
668            XmlReaderSettings xmlReaderSettings = GetXmlReaderSettings();
669            XmlParserContext xmlParserContext   = GetXmlParserContext();
670            return XmlReader.Create(textReader, xmlReaderSettings, xmlParserContext);
671        }
672
673        /// <summary>
674        /// Creates the validating XML reader.
675        /// </summary>
676        /// <param name="uri">The URI.</param>
677        /// <param name="stream">The stream.</param>
678        /// <returns></returns>
679        private XmlReader CreateValidatingXmlReader(string uri, Stream stream)
680        {
681            //return new XmlTextReader(uri, stream);
682            XmlReaderSettings xmlReaderSettings = GetXmlReaderSettings();
683            if (String.IsNullOrEmpty(uri))
684            {
685                return XmlReader.Create(stream, xmlReaderSettings, uri);
686            }
687            else
688            {
689                XmlParserContext xmlParserContext = GetXmlParserContext();
690                return XmlReader.Create(stream, xmlReaderSettings, xmlParserContext);
691            }
692        }
693
694        /// <summary>
695        /// Creates the validating XML reader.
696        /// </summary>
697        /// <param name="xmlReader">The XML reader.</param>
698        /// <returns></returns>
699        private XmlReader CreateValidatingXmlReader(XmlReader xmlReader)
700        {
701            // Note: we only have part of the job done here, we need to also use a parser context
702            return XmlReader.Create(xmlReader, GetXmlReaderSettings());
703        }
704
705        public XmlNode GetNodeByUri(Uri absoluteUri)
706        {
707            return GetNodeByUri(absoluteUri.AbsoluteUri);
708        }
709
710        public XmlNode GetNodeByUri(string absoluteUrl)
711        {
712            absoluteUrl = absoluteUrl.Trim();
713            if (absoluteUrl.StartsWith("#"))
714            {
715                return GetElementById(absoluteUrl.Substring(1));
716            }
717            else
718            {
719                Uri docUri = ResolveUri("");
720                Uri absoluteUri = new Uri(absoluteUrl);
721
722                string fragment = absoluteUri.Fragment;
723
724                if (fragment.Length == 0)
725                {
726                    // no fragment => return entire document
727                    if (docUri.AbsolutePath == absoluteUri.AbsolutePath)
728                    {
729                        return this;
730                    }
731                    else
732                    {
733                        SvgDocument doc = new SvgDocument((SvgWindow)Window);
734
735                        XmlReaderSettings settings = this.GetXmlReaderSettings();
736
737                        settings.CloseInput = true;
738
739                        //PrepareXmlResolver(settings);
740
741                        using (XmlReader reader = XmlReader.Create(
742                            GetResource(absoluteUri).GetResponseStream(), settings,
743                            absoluteUri.AbsolutePath))
744                        {
745                            doc.Load(reader);
746                        }
747                       
748                        return doc;
749                    }
750                }
751                else
752                {
753                    // got a fragment => return XmlElement
754                    string noFragment = absoluteUri.AbsoluteUri.Replace(fragment, "");
755                    SvgDocument doc = (SvgDocument)GetNodeByUri(new Uri(noFragment));
756                    return doc.GetElementById(fragment.Substring(1));
757                }
758            }
759        }
760
761        public Uri ResolveUri(string uri)
762        {
763            DirectoryInfo workingDir = this._window.WorkingDir;
764
765            string baseUri = BaseURI;
766            if (baseUri.Length == 0)
767            {
768                baseUri = "file:///" + workingDir.FullName.Replace('\\', '/');
769            }
770
771            return new Uri(new Uri(baseUri), uri);
772        }
773
774        #endregion
775
776        #region ISvgDocument Members
777
778        /// <summary>
779        /// The title of the document which is the text content of the first child title element of the 'svg' root element.
780        /// </summary>
781        public string Title
782        {
783            get
784            {
785                string result = "";
786
787                XmlNode node = SelectSingleNode("/svg:svg/svg:title[text()!='']", NamespaceManager);
788
789                if (node != null)
790                {
791                    node.Normalize();
792                    // NOTE: should probably use spec-defined whitespace
793                    result = Regex.Replace(node.InnerText, @"\s\s+", " ");
794                }
795
796                return result;
797            }
798        }
799
800        /// <summary>
801        /// Returns the URI of the page that linked to this page. The value is an empty string if the user navigated to the page directly (not through a link, but, for example, via a bookmark).
802        /// </summary>
803        public string Referrer
804        {
805            get
806            {
807                return String.Empty;
808            }
809        }
810
811        /// <summary>
812        /// The domain name of the server that served the document, or a null string if the server cannot be identified by a domain name.
813        /// </summary>
814        public string Domain
815        {
816            get
817            {
818                if (Url.Length == 0 ||
819                    Url.StartsWith(Uri.UriSchemeFile))
820                {
821                    return null;
822                }
823                else
824                {
825                    return new Uri(Url).Host;
826                }
827            }
828        }
829
830        /// <summary>
831        /// The root 'svg' element in the document hierarchy
832        /// </summary>
833        public ISvgSvgElement RootElement
834        {
835            get
836            {
837                return DocumentElement as ISvgSvgElement;
838            }
839        }
840
841        internal Dictionary<string, XmlElement> collectedIds;
842
843        public override XmlElement GetElementById(string elementId)
844        {
845            // TODO: handle element and attribute updates globally to watch for id changes.
846            if (collectedIds == null)
847            {
848                collectedIds = new Dictionary<string, XmlElement>();
849                // TODO: handle xml:id, handle duplicate ids?
850                XmlNodeList ids = this.SelectNodes("//*/@id");
851                foreach (XmlAttribute node in ids)
852                {
853                    try
854                    {
855                        collectedIds.Add(node.Value, node.OwnerElement);
856                    }
857                    catch
858                    {
859                        // Duplicate ID... what to do?
860                    }
861                }
862            }
863
864            // Find the item
865            if (collectedIds.ContainsKey(elementId))
866            {
867                return collectedIds[elementId];
868            }
869
870            return null;
871        }
872
873        #endregion
874
875        #region ISvgDocument Members from SVG 1.2
876
877        public ISvgWindow Window
878        {
879            get
880            {
881                return _window;
882            }
883        }
884
885        #endregion
886
887        #region Other public properties
888
889        public new SvgDocument OwnerDocument
890        {
891            get
892            {
893                return base.OwnerDocument as SvgDocument;
894            }
895        }
896
897        #endregion
898    }
899}
Note: See TracBrowser for help on using the repository browser.