SvgTextReader.cs 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Xml;
  6. using System.IO;
  7. using System.Collections.Specialized;
  8. #pragma warning disable
  9. namespace Svg
  10. {
  11. internal sealed class SvgTextReader : XmlTextReader
  12. {
  13. private Dictionary<string, string> _entities;
  14. private string _value;
  15. private bool _customValue = false;
  16. private string _localName;
  17. public SvgTextReader(Stream stream, Dictionary<string, string> entities)
  18. : base(stream)
  19. {
  20. this.EntityHandling = EntityHandling.ExpandEntities;
  21. this._entities = entities;
  22. }
  23. public SvgTextReader(TextReader reader, Dictionary<string, string> entities)
  24. : base(reader)
  25. {
  26. this.EntityHandling = EntityHandling.ExpandEntities;
  27. this._entities = entities;
  28. }
  29. /// <summary>
  30. /// Gets the text value of the current node.
  31. /// </summary>
  32. /// <value></value>
  33. /// <returns>The value returned depends on the <see cref="P:System.Xml.XmlTextReader.NodeType"/> of the node. The following table lists node types that have a value to return. All other node types return String.Empty.Node Type Value AttributeThe value of the attribute. CDATAThe content of the CDATA section. CommentThe content of the comment. DocumentTypeThe internal subset. ProcessingInstructionThe entire content, excluding the target. SignificantWhitespaceThe white space within an xml:space= 'preserve' scope. TextThe content of the text node. WhitespaceThe white space between markup. XmlDeclarationThe content of the declaration. </returns>
  34. public override string Value
  35. {
  36. get
  37. {
  38. if (this._customValue)
  39. return this._value;
  40. else
  41. return base.Value;
  42. }
  43. }
  44. /// <summary>
  45. /// Gets the local name of the current node.
  46. /// </summary>
  47. /// <value></value>
  48. /// <returns>The name of the current node with the prefix removed. For example, LocalName is book for the element &lt;bk:book&gt;.For node types that do not have a name (like Text, Comment, and so on), this property returns String.Empty.</returns>
  49. public override string LocalName
  50. {
  51. get
  52. {
  53. if (this._customValue)
  54. return this._localName;
  55. else
  56. return base.LocalName;
  57. }
  58. }
  59. private IDictionary<string, string> Entities
  60. {
  61. get
  62. {
  63. if (this._entities == null)
  64. {
  65. this._entities = new Dictionary<string, string>();
  66. }
  67. return this._entities;
  68. }
  69. }
  70. /// <summary>
  71. /// Moves to the next attribute.
  72. /// </summary>
  73. /// <returns>
  74. /// true if there is a next attribute; false if there are no more attributes.
  75. /// </returns>
  76. public override bool MoveToNextAttribute()
  77. {
  78. bool moved = base.MoveToNextAttribute();
  79. if (moved)
  80. {
  81. this._localName = base.LocalName;
  82. if (this.ReadAttributeValue())
  83. {
  84. if (this.NodeType == XmlNodeType.EntityReference)
  85. {
  86. this.ResolveEntity();
  87. }
  88. else
  89. {
  90. this._value = base.Value;
  91. }
  92. }
  93. this._customValue = true;
  94. }
  95. return moved;
  96. }
  97. /// <summary>
  98. /// Reads the next node from the stream.
  99. /// </summary>
  100. /// <returns>
  101. /// true if the next node was read successfully; false if there are no more nodes to read.
  102. /// </returns>
  103. /// <exception cref="T:System.Xml.XmlException">An error occurred while parsing the XML. </exception>
  104. public override bool Read()
  105. {
  106. this._customValue = false;
  107. bool read = base.Read();
  108. if (this.NodeType == XmlNodeType.DocumentType)
  109. {
  110. this.ParseEntities();
  111. }
  112. return read;
  113. }
  114. private void ParseEntities()
  115. {
  116. const string entityText = "<!ENTITY";
  117. string[] entities = this.Value.Split(new string[] { entityText }, StringSplitOptions.None);
  118. string name = null;
  119. string value = null;
  120. int quoteIndex;
  121. foreach (string entity in entities)
  122. {
  123. if (string.IsNullOrEmpty(entity.Trim()))
  124. {
  125. continue;
  126. }
  127. name = entity.Trim();
  128. quoteIndex = name.IndexOf(this.QuoteChar);
  129. if (quoteIndex > 0)
  130. {
  131. value = name.Substring(quoteIndex + 1, name.LastIndexOf(this.QuoteChar) - quoteIndex - 1);
  132. name = name.Substring(0, quoteIndex).Trim();
  133. this.Entities.Add(name, value);
  134. }
  135. }
  136. }
  137. /// <summary>
  138. /// Resolves the entity reference for EntityReference nodes.
  139. /// </summary>
  140. public override void ResolveEntity()
  141. {
  142. if (this.NodeType == XmlNodeType.EntityReference)
  143. {
  144. if (this._entities.ContainsKey(this.Name))
  145. {
  146. this._value = this._entities[this.Name];
  147. }
  148. else
  149. {
  150. this._value = string.Empty;
  151. }
  152. this._customValue = true;
  153. }
  154. }
  155. }
  156. }
  157. #pragma warning restore