DTDObjectModel.cs 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828
  1. //
  2. // Mono.Xml.DTDObjectModel
  3. //
  4. // Author:
  5. // Atsushi Enomoto ([email protected])
  6. //
  7. // (C)2003 Atsushi Enomoto
  8. //
  9. using System;
  10. using System.Collections;
  11. using System.Collections.Specialized;
  12. using System.Globalization;
  13. using System.IO;
  14. using System.Text;
  15. using System.Xml;
  16. using System.Xml.Schema;
  17. using Mono.Xml.Schema;
  18. using Mono.Xml.Native;
  19. namespace Mono.Xml
  20. {
  21. public class DTDObjectModel
  22. {
  23. DTDElementDeclarationCollection elementDecls;
  24. DTDAttListDeclarationCollection attListDecls;
  25. DTDEntityDeclarationCollection entityDecls;
  26. DTDNotationDeclarationCollection notationDecls;
  27. ArrayList validationErrors;
  28. XmlResolver resolver;
  29. public DTDObjectModel ()
  30. {
  31. elementDecls = new DTDElementDeclarationCollection (this);
  32. attListDecls = new DTDAttListDeclarationCollection (this);
  33. entityDecls = new DTDEntityDeclarationCollection (this);
  34. notationDecls = new DTDNotationDeclarationCollection (this);
  35. factory = new DTDAutomataFactory (this);
  36. validationErrors = new ArrayList ();
  37. }
  38. public string BaseURI;
  39. public string Name;
  40. public string PublicId;
  41. public string SystemId;
  42. public string InternalSubset;
  43. public bool InternalSubsetHasPEReference;
  44. public string ResolveEntity (string name)
  45. {
  46. DTDEntityDeclaration decl = EntityDecls [name]
  47. as DTDEntityDeclaration;
  48. return decl.EntityValue;
  49. }
  50. internal XmlResolver Resolver {
  51. get { return resolver; }
  52. }
  53. public XmlResolver XmlResolver {
  54. set { resolver = value; }
  55. }
  56. private DTDAutomataFactory factory;
  57. public DTDAutomataFactory Factory {
  58. get { return factory; }
  59. }
  60. public DTDElementDeclaration RootElement {
  61. get { return ElementDecls [Name]; }
  62. }
  63. public DTDElementDeclarationCollection ElementDecls {
  64. get { return elementDecls; }
  65. }
  66. public DTDAttListDeclarationCollection AttListDecls {
  67. get { return attListDecls; }
  68. }
  69. public DTDEntityDeclarationCollection EntityDecls {
  70. get { return entityDecls; }
  71. }
  72. public DTDNotationDeclarationCollection NotationDecls {
  73. get { return notationDecls; }
  74. }
  75. DTDElementAutomata rootAutomata;
  76. public DTDAutomata RootAutomata {
  77. get {
  78. if (rootAutomata == null)
  79. rootAutomata = new DTDElementAutomata (this, this.Name);
  80. return rootAutomata;
  81. }
  82. }
  83. DTDEmptyAutomata emptyAutomata;
  84. public DTDEmptyAutomata Empty {
  85. get {
  86. if (emptyAutomata == null)
  87. emptyAutomata = new DTDEmptyAutomata (this);
  88. return emptyAutomata;
  89. }
  90. }
  91. DTDAnyAutomata anyAutomata;
  92. public DTDAnyAutomata Any {
  93. get {
  94. if (anyAutomata == null)
  95. anyAutomata = new DTDAnyAutomata (this);
  96. return anyAutomata;
  97. }
  98. }
  99. DTDInvalidAutomata invalidAutomata;
  100. public DTDInvalidAutomata Invalid {
  101. get {
  102. if (invalidAutomata == null)
  103. invalidAutomata = new DTDInvalidAutomata (this);
  104. return invalidAutomata;
  105. }
  106. }
  107. public XmlSchemaException [] Errors {
  108. get { return validationErrors.ToArray (typeof (XmlSchemaException)) as XmlSchemaException []; }
  109. }
  110. public void AddError (XmlSchemaException ex)
  111. {
  112. validationErrors.Add (ex);
  113. }
  114. }
  115. public class DTDElementDeclarationCollection
  116. {
  117. Hashtable elementDecls = new Hashtable ();
  118. DTDObjectModel root;
  119. public DTDElementDeclarationCollection (DTDObjectModel root)
  120. {
  121. this.root = root;
  122. }
  123. public DTDElementDeclaration this [string name] {
  124. get { return elementDecls [name] as DTDElementDeclaration; }
  125. }
  126. public void Add (string name, DTDElementDeclaration decl)
  127. {
  128. if (elementDecls [name] != null) {
  129. this.root.AddError (new XmlSchemaException (String.Format (
  130. "Element declaration for {0} was already added.",
  131. name), null));
  132. return;
  133. }
  134. decl.SetRoot (root);
  135. elementDecls.Add (name, decl);
  136. }
  137. public ICollection Keys {
  138. get { return elementDecls.Keys; }
  139. }
  140. public ICollection Values {
  141. get { return elementDecls.Values; }
  142. }
  143. }
  144. public class DTDAttListDeclarationCollection
  145. {
  146. Hashtable attListDecls = new Hashtable ();
  147. DTDObjectModel root;
  148. public DTDAttListDeclarationCollection (DTDObjectModel root)
  149. {
  150. this.root = root;
  151. }
  152. public DTDAttListDeclaration this [string name] {
  153. get { return attListDecls [name] as DTDAttListDeclaration; }
  154. }
  155. public void Add (string name, DTDAttListDeclaration decl)
  156. {
  157. DTDAttListDeclaration existing = this [name];
  158. if (existing != null) {
  159. // It should be valid and
  160. // has effect of additive declaration.
  161. foreach (DTDAttributeDefinition def in decl.Definitions)
  162. if (decl.Get (def.Name) == null)
  163. existing.Add (def);
  164. } else {
  165. decl.SetRoot (root);
  166. attListDecls.Add (name, decl);
  167. }
  168. }
  169. public ICollection Keys {
  170. get { return attListDecls.Keys; }
  171. }
  172. public ICollection Values {
  173. get { return attListDecls.Values; }
  174. }
  175. }
  176. public class DTDEntityDeclarationCollection
  177. {
  178. Hashtable entityDecls = new Hashtable ();
  179. DTDObjectModel root;
  180. public DTDEntityDeclarationCollection (DTDObjectModel root)
  181. {
  182. this.root = root;
  183. }
  184. public DTDEntityDeclaration this [string name] {
  185. get { return entityDecls [name] as DTDEntityDeclaration; }
  186. }
  187. public void Add (string name, DTDEntityDeclaration decl)
  188. {
  189. if (entityDecls [name] != null)
  190. throw new InvalidOperationException (String.Format (
  191. "Entity declaration for {0} was already added.",
  192. name));
  193. decl.SetRoot (root);
  194. entityDecls.Add (name, decl);
  195. }
  196. public ICollection Keys {
  197. get { return entityDecls.Keys; }
  198. }
  199. public ICollection Values {
  200. get { return entityDecls.Values; }
  201. }
  202. }
  203. public class DTDNotationDeclarationCollection
  204. {
  205. Hashtable notationDecls = new Hashtable ();
  206. DTDObjectModel root;
  207. public DTDNotationDeclarationCollection (DTDObjectModel root)
  208. {
  209. this.root = root;
  210. }
  211. public DTDNotationDeclaration this [string name] {
  212. get { return notationDecls [name] as DTDNotationDeclaration; }
  213. }
  214. public void Add (string name, DTDNotationDeclaration decl)
  215. {
  216. if (notationDecls [name] != null)
  217. throw new InvalidOperationException (String.Format (
  218. "Notation declaration for {0} was already added.",
  219. name));
  220. decl.SetRoot (root);
  221. notationDecls.Add (name, decl);
  222. }
  223. public ICollection Keys {
  224. get { return notationDecls.Keys; }
  225. }
  226. public ICollection Values {
  227. get { return notationDecls.Values; }
  228. }
  229. }
  230. public class DTDContentModel
  231. {
  232. private DTDObjectModel root;
  233. DTDAutomata compiledAutomata;
  234. private string ownerElementName;
  235. public string ElementName;
  236. public DTDContentOrderType OrderType = DTDContentOrderType.None;
  237. public DTDContentModelCollection ChildModels
  238. = new DTDContentModelCollection ();
  239. public DTDOccurence Occurence = DTDOccurence.One;
  240. internal DTDContentModel (DTDObjectModel root, string ownerElementName)
  241. {
  242. this.root = root;
  243. this.ownerElementName = ownerElementName;
  244. }
  245. public DTDElementDeclaration ElementDecl {
  246. get {
  247. return root.ElementDecls [ownerElementName];
  248. }
  249. }
  250. public DTDAutomata GetAutomata ()
  251. {
  252. if (compiledAutomata == null)
  253. Compile ();
  254. return compiledAutomata;
  255. }
  256. public DTDAutomata Compile ()
  257. {
  258. compiledAutomata = CompileInternal ();
  259. return compiledAutomata;
  260. }
  261. private DTDAutomata CompileInternal ()
  262. {
  263. if (ElementDecl.IsAny)
  264. return root.Any;
  265. if (ElementDecl.IsEmpty)
  266. return root.Empty;
  267. DTDAutomata basis = GetBasicContentAutomata ();
  268. switch (Occurence) {
  269. case DTDOccurence.One:
  270. return basis;
  271. case DTDOccurence.Optional:
  272. return Choice (root.Empty, basis);
  273. case DTDOccurence.OneOrMore:
  274. return new DTDOneOrMoreAutomata (root, basis);
  275. case DTDOccurence.ZeroOrMore:
  276. return Choice (root.Empty, new DTDOneOrMoreAutomata (root, basis));
  277. }
  278. throw new InvalidOperationException ();
  279. }
  280. private DTDAutomata GetBasicContentAutomata ()
  281. {
  282. if (ElementName != null)
  283. return new DTDElementAutomata (root, ElementName);
  284. switch (ChildModels.Count) {
  285. case 0:
  286. return root.Empty;
  287. case 1:
  288. return ChildModels [0].GetAutomata ();
  289. }
  290. DTDAutomata current = null;
  291. int childCount = ChildModels.Count;
  292. switch (OrderType) {
  293. case DTDContentOrderType.Seq:
  294. current = Sequence (
  295. ChildModels [childCount - 2].GetAutomata (),
  296. ChildModels [childCount - 1].GetAutomata ());
  297. for (int i = childCount - 2; i > 0; i--)
  298. current = Sequence (
  299. ChildModels [i - 1].GetAutomata (), current);
  300. return current;
  301. case DTDContentOrderType.Or:
  302. current = Choice (
  303. ChildModels [childCount - 2].GetAutomata (),
  304. ChildModels [childCount - 1].GetAutomata ());
  305. for (int i = childCount - 2; i > 0; i--)
  306. current = Choice (
  307. ChildModels [i - 1].GetAutomata (), current);
  308. return current;
  309. default:
  310. throw new InvalidOperationException ("Invalid pattern specification");
  311. }
  312. }
  313. private DTDAutomata Sequence (DTDAutomata l, DTDAutomata r)
  314. {
  315. return root.Factory.Sequence (l, r);
  316. }
  317. private DTDAutomata Choice (DTDAutomata l, DTDAutomata r)
  318. {
  319. return l.MakeChoice (r);
  320. }
  321. }
  322. public class DTDContentModelCollection
  323. {
  324. ArrayList contentModel = new ArrayList ();
  325. public DTDContentModelCollection ()
  326. {
  327. }
  328. public DTDContentModel this [int i] {
  329. get { return contentModel [i] as DTDContentModel; }
  330. }
  331. public int Count {
  332. get { return contentModel.Count; }
  333. }
  334. public void Add (DTDContentModel model)
  335. {
  336. contentModel.Add (model);
  337. }
  338. }
  339. public abstract class DTDNode
  340. {
  341. private DTDObjectModel root;
  342. public string BaseURI;
  343. public int LineNumber;
  344. public int LinePosition;
  345. internal void SetRoot (DTDObjectModel root)
  346. {
  347. this.root = root;
  348. if (BaseURI == null)
  349. this.BaseURI = root.BaseURI;
  350. }
  351. protected DTDObjectModel Root {
  352. get { return root; }
  353. }
  354. }
  355. public class DTDElementDeclaration : DTDNode // : ICloneable
  356. {
  357. public string Name;
  358. public bool IsEmpty;
  359. public bool IsAny;
  360. public bool IsMixedContent;
  361. public DTDContentModel contentModel;
  362. DTDObjectModel root;
  363. internal DTDElementDeclaration (DTDObjectModel root)
  364. {
  365. this.root = root;
  366. }
  367. public DTDContentModel ContentModel {
  368. get {
  369. if (contentModel == null)
  370. contentModel = new DTDContentModel (root, Name);
  371. return contentModel;
  372. }
  373. }
  374. public DTDAttListDeclaration Attributes {
  375. get {
  376. return Root.AttListDecls [Name];
  377. }
  378. }
  379. // public object Clone ()
  380. // {
  381. // return this.MemberwiseClone ();
  382. // }
  383. }
  384. public class DTDAttributeDefinition : DTDNode// : ICloneable
  385. {
  386. public string Name;
  387. public XmlSchemaDatatype Datatype;
  388. // entity reference inside enumerated values are not allowed,
  389. // but on the other hand, they are allowed inside default value.
  390. // Then I decided to use string ArrayList for enumerated values,
  391. // and unresolved string value for DefaultValue.
  392. public ArrayList EnumeratedAttributeDeclaration = new ArrayList ();
  393. public string UnresolvedDefaultValue = null;
  394. public ArrayList EnumeratedNotations = new ArrayList();
  395. public DTDAttributeOccurenceType OccurenceType = DTDAttributeOccurenceType.None;
  396. private string resolvedDefaultValue;
  397. private string resolvedNormalizedDefaultValue;
  398. internal DTDAttributeDefinition () {}
  399. public string DefaultValue {
  400. get {
  401. if (resolvedDefaultValue == null)
  402. resolvedDefaultValue = ComputeDefaultValue ();
  403. return resolvedDefaultValue;
  404. }
  405. }
  406. public string NormalizedDefaultValue {
  407. get {
  408. if (resolvedNormalizedDefaultValue == null) {
  409. object o = Datatype.ParseValue (ComputeDefaultValue (), null, null);
  410. resolvedNormalizedDefaultValue =
  411. (o is string []) ?
  412. String.Join (" ", (string []) o) :
  413. o.ToString ();
  414. }
  415. return resolvedNormalizedDefaultValue;
  416. }
  417. }
  418. private string ComputeDefaultValue ()
  419. {
  420. if (UnresolvedDefaultValue == null)
  421. return null;
  422. StringBuilder sb = new StringBuilder ();
  423. int pos = 0;
  424. int next = 0;
  425. string value = this.UnresolvedDefaultValue;
  426. while ((next = value.IndexOf ('&', pos)) >= 0) {
  427. int semicolon = value.IndexOf (';', next);
  428. if (value [next + 1] == '#') {
  429. // character reference.
  430. char c = value [next + 2];
  431. NumberStyles style = NumberStyles.Integer;
  432. string spec;
  433. if (c == 'x' || c == 'X') {
  434. spec = value.Substring (next + 3, semicolon - next - 3);
  435. style |= NumberStyles.HexNumber;
  436. }
  437. else
  438. spec = value.Substring (next + 2, semicolon - next - 2);
  439. sb.Append ((char) int.Parse (spec, style));
  440. } else {
  441. sb.Append (value.Substring (pos, next - 1));
  442. string name = value.Substring (pos + 1, semicolon - 1);
  443. char predefined = XmlChar.GetPredefinedEntity (name);
  444. if (predefined != 0)
  445. sb.Append (predefined);
  446. else
  447. sb.Append (Root.ResolveEntity (name));
  448. }
  449. pos = semicolon + 1;
  450. }
  451. sb.Append (value.Substring (pos));
  452. // strip quote chars
  453. string ret = sb.ToString (1, sb.Length - 2);
  454. sb.Length = 0;
  455. return ret;
  456. }
  457. public char QuoteChar {
  458. get {
  459. return UnresolvedDefaultValue.Length > 0 ?
  460. this.UnresolvedDefaultValue [0] :
  461. '"';
  462. }
  463. }
  464. // public object Clone ()
  465. // {
  466. // return this.MemberwiseClone ();
  467. // }
  468. }
  469. public class DTDAttListDeclaration : DTDNode // : ICloneable
  470. {
  471. public string Name;
  472. internal DTDAttListDeclaration (DTDObjectModel root)
  473. {
  474. SetRoot (root);
  475. }
  476. private Hashtable attributeOrders = new Hashtable ();
  477. private ArrayList attributes = new ArrayList ();
  478. public DTDAttributeDefinition this [int i] {
  479. get { return Get (i); }
  480. }
  481. public DTDAttributeDefinition this [string name] {
  482. get { return Get (name); }
  483. }
  484. public DTDAttributeDefinition Get (int i)
  485. {
  486. return attributes [i] as DTDAttributeDefinition;
  487. }
  488. public DTDAttributeDefinition Get (string name)
  489. {
  490. object o = attributeOrders [name];
  491. if (o != null)
  492. return attributes [(int) o] as DTDAttributeDefinition;
  493. else
  494. return null;
  495. }
  496. public ICollection Definitions {
  497. get { return attributes; }
  498. }
  499. public void Add (DTDAttributeDefinition def)
  500. {
  501. if (attributeOrders [def.Name] != null)
  502. throw new InvalidOperationException (String.Format (
  503. "Attribute definition for {0} was already added at element {1}.",
  504. def.Name, this.Name));
  505. def.SetRoot (Root);
  506. attributeOrders.Add (def.Name, attributes.Count);
  507. attributes.Add (def);
  508. }
  509. public int Count {
  510. get { return attributeOrders.Count; }
  511. }
  512. // public object Clone ()
  513. // {
  514. // return this.MemberwiseClone ();
  515. // }
  516. }
  517. public class DTDEntityDeclaration : DTDNode
  518. {
  519. string entityValue;
  520. public string Name;
  521. public string PublicId;
  522. public string SystemId;
  523. public string NotationName;
  524. public string LiteralEntityValue;
  525. public bool IsInternalSubset;
  526. public StringCollection ReferencingEntities = new StringCollection ();
  527. bool scanned;
  528. bool recursed;
  529. public string EntityValue {
  530. get {
  531. if (entityValue == null) {
  532. if (NotationName != null)
  533. entityValue = "";
  534. else if (SystemId == null)
  535. entityValue = LiteralEntityValue;
  536. else {
  537. // FIXME: should use specified XmlUrlResolver.
  538. entityValue = ResolveExternalEntity (Root.Resolver);
  539. }
  540. // Check illegal recursion.
  541. ScanEntityValue (new StringCollection ());
  542. }
  543. return entityValue;
  544. }
  545. }
  546. public void ScanEntityValue (StringCollection refs)
  547. {
  548. // To modify this code, beware nesting between this and EntityValue.
  549. string value = EntityValue;
  550. if (recursed)
  551. throw new XmlException ("Entity recursion was found.");
  552. recursed = true;
  553. if (scanned) {
  554. foreach (string referenced in refs)
  555. if (this.ReferencingEntities.Contains (referenced))
  556. throw new XmlException (String.Format (
  557. "Nested entity was found between {0} and {1}",
  558. referenced, Name));
  559. recursed = false;
  560. return;
  561. }
  562. int len = value.Length;
  563. int start = 0;
  564. for (int i=0; i<len; i++) {
  565. switch (value [i]) {
  566. case '&':
  567. start = i+1;
  568. break;
  569. case ';':
  570. if (start == 0)
  571. break;
  572. string name = value.Substring (start, i - start);
  573. this.ReferencingEntities.Add (name);
  574. DTDEntityDeclaration decl = Root.EntityDecls [name];
  575. if (decl != null) {
  576. refs.Add (Name);
  577. decl.ScanEntityValue (refs);
  578. foreach (string str in decl.ReferencingEntities)
  579. ReferencingEntities.Add (str);
  580. refs.Remove (Name);
  581. }
  582. start = 0;
  583. break;
  584. }
  585. }
  586. scanned = true;
  587. recursed = false;
  588. }
  589. private string ResolveExternalEntity (XmlResolver resolver)
  590. {
  591. if (resolver == null)
  592. return String.Empty;
  593. string baseUri = Root.BaseURI;
  594. if (baseUri == "")
  595. baseUri = null;
  596. Uri uri = resolver.ResolveUri (
  597. baseUri != null ? new Uri (baseUri) : null, SystemId);
  598. Stream stream = resolver.GetEntity (uri, null, typeof (Stream)) as Stream;
  599. XmlStreamReader reader = new XmlStreamReader (stream, false);
  600. StringBuilder sb = new StringBuilder ();
  601. bool checkTextDecl = true;
  602. while (reader.Peek () != -1) {
  603. sb.Append ((char) reader.Read ());
  604. if (checkTextDecl && sb.Length == 6) {
  605. if (sb.ToString () == "<?xml ") {
  606. // Skip Text declaration.
  607. sb.Length = 0;
  608. StringBuilder textdecl = new StringBuilder ();
  609. while (reader.Peek () != '>' && reader.Peek () != -1)
  610. textdecl.Append ((char) reader.Read ());
  611. if (textdecl.ToString ().IndexOf ("encoding") < 0)
  612. throw new XmlException ("Text declaration must have encoding specification: " + BaseURI);
  613. if (textdecl.ToString ().IndexOf ("standalone") >= 0)
  614. throw new XmlException ("Text declaration cannot have standalone declaration: " + BaseURI);
  615. }
  616. checkTextDecl = false;
  617. }
  618. }
  619. return sb.ToString ();
  620. }
  621. internal DTDEntityDeclaration (DTDObjectModel root)
  622. {
  623. this.SetRoot (root);
  624. }
  625. }
  626. public class DTDNotationDeclaration : DTDNode
  627. {
  628. public string Name;
  629. public string LocalName;
  630. public string Prefix;
  631. public string PublicId;
  632. public string SystemId;
  633. internal DTDNotationDeclaration () {}
  634. }
  635. public class DTDParameterEntityDeclaration : DTDNode
  636. {
  637. string resolvedValue;
  638. Exception loadException;
  639. public string Name;
  640. public string PublicId;
  641. public string SystemId;
  642. public string LiteralValue;
  643. public bool LoadFailed;
  644. public string Value {
  645. get {
  646. if (LiteralValue != null)
  647. return LiteralValue;
  648. if (resolvedValue == null)
  649. throw new InvalidOperationException ();
  650. return resolvedValue;
  651. }
  652. }
  653. public void Resolve (XmlResolver resolver)
  654. {
  655. if (resolver == null) {
  656. resolvedValue = String.Empty;
  657. LoadFailed = true;
  658. return;
  659. }
  660. Uri baseUri = null;
  661. try {
  662. baseUri = new Uri (BaseURI);
  663. } catch (UriFormatException) {
  664. }
  665. Uri absUri = resolver.ResolveUri (baseUri, SystemId);
  666. string absPath = absUri.ToString ();
  667. try {
  668. XmlStreamReader tw = new XmlStreamReader (absUri.ToString (), false, resolver, BaseURI);
  669. string s = tw.ReadToEnd ();
  670. if (s.StartsWith ("<?xml")) {
  671. int end = s.IndexOf (">") + 1;
  672. if (end < 0)
  673. throw new XmlException (this as IXmlLineInfo,
  674. "Inconsistent text declaration markup.");
  675. if (s.IndexOf ("encoding", 0, end) < 0)
  676. throw new XmlException (this as IXmlLineInfo,
  677. "Text declaration must not omit encoding specification.");
  678. if (s.IndexOf ("standalone", 0, end) >= 0)
  679. throw new XmlException (this as IXmlLineInfo,
  680. "Text declaration cannot have standalone declaration.");
  681. resolvedValue = s.Substring (end);
  682. }
  683. else
  684. resolvedValue = s;
  685. } catch (IOException ex) {
  686. loadException = ex;
  687. resolvedValue = String.Empty;
  688. LoadFailed = true;
  689. }
  690. }
  691. }
  692. public enum DTDContentOrderType
  693. {
  694. None,
  695. Seq,
  696. Or
  697. }
  698. public enum DTDAttributeOccurenceType
  699. {
  700. None,
  701. Required,
  702. Optional,
  703. Fixed
  704. }
  705. public enum DTDOccurence
  706. {
  707. One,
  708. Optional,
  709. ZeroOrMore,
  710. OneOrMore
  711. }
  712. }