2 // Mono.Xml.DTDObjectModel
5 // Atsushi Enomoto (ginga@kit.hi-ho.ne.jp)
7 // (C)2003 Atsushi Enomoto
11 // Permission is hereby granted, free of charge, to any person obtaining
12 // a copy of this software and associated documentation files (the
13 // "Software"), to deal in the Software without restriction, including
14 // without limitation the rights to use, copy, modify, merge, publish,
15 // distribute, sublicense, and/or sell copies of the Software, and to
16 // permit persons to whom the Software is furnished to do so, subject to
17 // the following conditions:
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
22 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 using System
.Collections
;
32 using System
.Globalization
;
36 using System
.Xml
.Schema
;
37 using Mono
.Xml
.Schema
;
40 using XmlTextReaderImpl
= Mono
.Xml2
.XmlTextReader
;
42 using XmlTextReaderImpl
= System
.Xml
.XmlTextReader
;
47 internal class DTDObjectModel
49 // This specifies the max number of dependent external entities
50 // per a DTD can consume. A malicious external document server
51 // might send users' document processing server a large number
52 // of external entities.
53 public const int AllowedExternalEntitiesMax
= 256;
55 DTDAutomataFactory factory
;
56 DTDElementAutomata rootAutomata
;
57 DTDEmptyAutomata emptyAutomata
;
58 DTDAnyAutomata anyAutomata
;
59 DTDInvalidAutomata invalidAutomata
;
61 DTDElementDeclarationCollection elementDecls
;
62 DTDAttListDeclarationCollection attListDecls
;
63 DTDParameterEntityDeclarationCollection peDecls
;
64 DTDEntityDeclarationCollection entityDecls
;
65 DTDNotationDeclarationCollection notationDecls
;
66 ArrayList validationErrors
;
68 XmlNameTable nameTable
;
70 Hashtable externalResources
;
77 bool intSubsetHasPERef
;
82 public DTDObjectModel (XmlNameTable nameTable
)
84 this.nameTable
= nameTable
;
85 elementDecls
= new DTDElementDeclarationCollection (this);
86 attListDecls
= new DTDAttListDeclarationCollection (this);
87 entityDecls
= new DTDEntityDeclarationCollection (this);
88 peDecls
= new DTDParameterEntityDeclarationCollection (this);
89 notationDecls
= new DTDNotationDeclarationCollection (this);
90 factory
= new DTDAutomataFactory (this);
91 validationErrors
= new ArrayList ();
92 externalResources
= new Hashtable ();
95 public string BaseURI
{
96 get { return baseURI; }
97 set { baseURI = value; }
100 public bool IsStandalone
{
101 get { return isStandalone; }
102 set { isStandalone = value; }
107 set { name = value; }
110 public XmlNameTable NameTable
{
111 get { return nameTable; }
114 public string PublicId
{
115 get { return publicId; }
116 set { publicId = value; }
119 public string SystemId
{
120 get { return systemId; }
121 set { systemId = value; }
124 public string InternalSubset
{
125 get { return intSubset; }
126 set { intSubset = value; }
129 public bool InternalSubsetHasPEReference
{
130 get { return intSubsetHasPERef; }
131 set { intSubsetHasPERef = value; }
134 public int LineNumber
{
135 get { return lineNumber; }
136 set { lineNumber = value; }
139 public int LinePosition
{
140 get { return linePosition; }
141 set { linePosition = value; }
144 public string ResolveEntity (string name
)
146 DTDEntityDeclaration decl
= EntityDecls
[name
]
147 as DTDEntityDeclaration
;
149 AddError (new XmlSchemaException ("Required entity was not found.",
150 this.LineNumber
, this.LinePosition
, null, this.BaseURI
, null));
154 return decl
.EntityValue
;
157 internal XmlResolver Resolver
{
158 get { return resolver; }
161 public XmlResolver XmlResolver
{
162 set { resolver = value; }
165 internal Hashtable ExternalResources
{
166 get { return externalResources; }
169 public DTDAutomataFactory Factory
{
170 get { return factory; }
173 public DTDElementDeclaration RootElement
{
174 get { return ElementDecls [Name]; }
177 public DTDElementDeclarationCollection ElementDecls
{
178 get { return elementDecls; }
181 public DTDAttListDeclarationCollection AttListDecls
{
182 get { return attListDecls; }
185 public DTDEntityDeclarationCollection EntityDecls
{
186 get { return entityDecls; }
189 public DTDParameterEntityDeclarationCollection PEDecls
{
190 get { return peDecls; }
193 public DTDNotationDeclarationCollection NotationDecls
{
194 get { return notationDecls; }
197 public DTDAutomata RootAutomata
{
199 if (rootAutomata
== null)
200 rootAutomata
= new DTDElementAutomata (this, this.Name
);
205 public DTDEmptyAutomata Empty
{
207 if (emptyAutomata
== null)
208 emptyAutomata
= new DTDEmptyAutomata (this);
209 return emptyAutomata
;
213 public DTDAnyAutomata Any
{
215 if (anyAutomata
== null)
216 anyAutomata
= new DTDAnyAutomata (this);
221 public DTDInvalidAutomata Invalid
{
223 if (invalidAutomata
== null)
224 invalidAutomata
= new DTDInvalidAutomata (this);
225 return invalidAutomata
;
229 public XmlSchemaException
[] Errors
{
230 get { return validationErrors.ToArray (typeof (XmlSchemaException)) as XmlSchemaException []; }
233 public void AddError (XmlSchemaException ex
)
235 validationErrors
.Add (ex
);
239 internal string GenerateEntityAttributeText (string entityName
)
241 DTDEntityDeclaration entity
= EntityDecls
[entityName
] as DTDEntityDeclaration
;
244 return entity
.EntityValue
;
247 internal XmlTextReaderImpl
GenerateEntityContentReader (string entityName
, XmlParserContext context
)
249 DTDEntityDeclaration entity
= EntityDecls
[entityName
] as DTDEntityDeclaration
;
253 if (entity
.SystemId
!= null) {
254 Uri baseUri
= entity
.BaseURI
== null ? null : new Uri (entity
.BaseURI
);
255 Stream stream
= resolver
.GetEntity (resolver
.ResolveUri (baseUri
, entity
.SystemId
), null, typeof (Stream
)) as Stream
;
256 return new XmlTextReaderImpl (stream
, XmlNodeType
.Element
, context
);
259 return new XmlTextReaderImpl (entity
.EntityValue
, XmlNodeType
.Element
, context
);
264 internal class DTDCollectionBase
: DictionaryBase
268 protected DTDCollectionBase (DTDObjectModel root
)
273 protected DTDObjectModel Root
{
277 public ICollection Keys
{
278 get { return InnerHashtable.Keys; }
281 public ICollection Values
{
282 get { return InnerHashtable.Values; }
286 internal class DTDElementDeclarationCollection
: DTDCollectionBase
289 public DTDElementDeclarationCollection (DTDObjectModel root
) : base (root
) {}
291 public DTDElementDeclaration
this [string name
] {
292 get { return Get (name); }
295 public DTDElementDeclaration
Get (string name
)
297 return InnerHashtable
[name
] as DTDElementDeclaration
;
300 public void Add (string name
, DTDElementDeclaration decl
)
302 if (InnerHashtable
.Contains (name
)) {
303 Root
.AddError (new XmlSchemaException (String
.Format (
304 "Element declaration for {0} was already added.",
309 InnerHashtable
.Add (name
, decl
);
313 internal class DTDAttListDeclarationCollection
: DTDCollectionBase
315 public DTDAttListDeclarationCollection (DTDObjectModel root
) : base (root
) {}
317 public DTDAttListDeclaration
this [string name
] {
318 get { return InnerHashtable [name] as DTDAttListDeclaration; }
321 public void Add (string name
, DTDAttListDeclaration decl
)
323 DTDAttListDeclaration existing
= this [name
];
324 if (existing
!= null) {
325 // It is valid, that is additive declaration.
326 foreach (DTDAttributeDefinition def
in decl
.Definitions
)
327 if (decl
.Get (def
.Name
) == null)
331 InnerHashtable
.Add (name
, decl
);
336 internal class DTDEntityDeclarationCollection
: DTDCollectionBase
338 public DTDEntityDeclarationCollection (DTDObjectModel root
) : base (root
) {}
340 public DTDEntityDeclaration
this [string name
] {
341 get { return InnerHashtable [name] as DTDEntityDeclaration; }
344 public void Add (string name
, DTDEntityDeclaration decl
)
346 if (InnerHashtable
[name
] != null)
347 throw new InvalidOperationException (String
.Format (
348 "Entity declaration for {0} was already added.",
351 InnerHashtable
.Add (name
, decl
);
355 internal class DTDNotationDeclarationCollection
: DTDCollectionBase
357 public DTDNotationDeclarationCollection (DTDObjectModel root
) : base (root
) {}
359 public DTDNotationDeclaration
this [string name
] {
360 get { return InnerHashtable [name] as DTDNotationDeclaration; }
363 public void Add (string name
, DTDNotationDeclaration decl
)
365 if (InnerHashtable
[name
] != null)
366 throw new InvalidOperationException (String
.Format (
367 "Notation declaration for {0} was already added.",
370 InnerHashtable
.Add (name
, decl
);
374 // This class contains either ElementName or ChildModels.
375 internal class DTDContentModel
: DTDNode
378 DTDAutomata compiledAutomata
;
380 string ownerElementName
;
382 DTDContentOrderType orderType
= DTDContentOrderType
.None
;
383 DTDContentModelCollection childModels
= new DTDContentModelCollection ();
384 DTDOccurence occurence
= DTDOccurence
.One
;
386 internal DTDContentModel (DTDObjectModel root
, string ownerElementName
)
389 this.ownerElementName
= ownerElementName
;
392 public DTDContentModelCollection ChildModels
{
393 get { return childModels; }
394 set { childModels = value; }
397 public DTDElementDeclaration ElementDecl
{
398 get { return root.ElementDecls [ownerElementName]; }
401 public string ElementName
{
402 get { return elementName; }
403 set { elementName = value; }
406 public DTDOccurence Occurence
{
407 get { return occurence; }
408 set { occurence = value; }
411 public DTDContentOrderType OrderType
{
412 get { return orderType; }
413 set { orderType = value; }
416 public DTDAutomata
GetAutomata ()
418 if (compiledAutomata
== null)
420 return compiledAutomata
;
423 public DTDAutomata
Compile ()
425 compiledAutomata
= CompileInternal ();
426 return compiledAutomata
;
429 private DTDAutomata
CompileInternal ()
431 if (ElementDecl
.IsAny
)
433 if (ElementDecl
.IsEmpty
)
436 DTDAutomata basis
= GetBasicContentAutomata ();
438 case DTDOccurence
.One
:
440 case DTDOccurence
.Optional
:
441 return Choice (root
.Empty
, basis
);
442 case DTDOccurence
.OneOrMore
:
443 return new DTDOneOrMoreAutomata (root
, basis
);
444 case DTDOccurence
.ZeroOrMore
:
445 return Choice (root
.Empty
, new DTDOneOrMoreAutomata (root
, basis
));
447 throw new InvalidOperationException ();
450 private DTDAutomata
GetBasicContentAutomata ()
452 if (ElementName
!= null)
453 return new DTDElementAutomata (root
, ElementName
);
454 switch (ChildModels
.Count
) {
458 return ChildModels
[0].GetAutomata ();
461 DTDAutomata current
= null;
462 int childCount
= ChildModels
.Count
;
464 case DTDContentOrderType
.Seq
:
466 ChildModels
[childCount
- 2].GetAutomata (),
467 ChildModels
[childCount
- 1].GetAutomata ());
468 for (int i
= childCount
- 2; i
> 0; i
--)
470 ChildModels
[i
- 1].GetAutomata (), current
);
472 case DTDContentOrderType
.Or
:
474 ChildModels
[childCount
- 2].GetAutomata (),
475 ChildModels
[childCount
- 1].GetAutomata ());
476 for (int i
= childCount
- 2; i
> 0; i
--)
478 ChildModels
[i
- 1].GetAutomata (), current
);
481 throw new InvalidOperationException ("Invalid pattern specification");
485 private DTDAutomata
Sequence (DTDAutomata l
, DTDAutomata r
)
487 return root
.Factory
.Sequence (l
, r
);
490 private DTDAutomata
Choice (DTDAutomata l
, DTDAutomata r
)
492 return l
.MakeChoice (r
);
497 internal class DTDContentModelCollection
499 ArrayList contentModel
= new ArrayList ();
501 public DTDContentModelCollection ()
505 public DTDContentModel
this [int i
] {
506 get { return contentModel [i] as DTDContentModel; }
510 get { return contentModel.Count; }
513 public void Add (DTDContentModel model
)
515 contentModel
.Add (model
);
519 internal abstract class DTDNode
: IXmlLineInfo
522 bool isInternalSubset
;
527 public virtual string BaseURI
{
528 get { return baseURI; }
529 set { baseURI = value; }
532 public bool IsInternalSubset
{
533 get { return isInternalSubset; }
534 set { isInternalSubset = value; }
537 public int LineNumber
{
538 get { return lineNumber; }
539 set { lineNumber = value; }
542 public int LinePosition
{
543 get { return linePosition; }
544 set { linePosition = value; }
547 public bool HasLineInfo ()
549 return lineNumber
!= 0;
552 internal void SetRoot (DTDObjectModel root
)
556 this.BaseURI
= root
.BaseURI
;
559 protected DTDObjectModel Root
{
563 internal XmlException
NotWFError (string message
)
565 return new XmlException (this as IXmlLineInfo
, BaseURI
, message
);
569 internal class DTDElementDeclaration
: DTDNode
572 DTDContentModel contentModel
;
578 internal DTDElementDeclaration (DTDObjectModel root
)
585 set { name = value; }
587 public bool IsEmpty
{
588 get { return isEmpty; }
589 set { isEmpty = value; }
593 get { return isAny; }
594 set { isAny = value; }
597 public bool IsMixedContent
{
598 get { return isMixedContent; }
599 set { isMixedContent = value; }
602 public DTDContentModel ContentModel
{
604 if (contentModel
== null)
605 contentModel
= new DTDContentModel (root
, Name
);
610 public DTDAttListDeclaration Attributes
{
612 return Root
.AttListDecls
[Name
];
617 internal class DTDAttributeDefinition
: DTDNode
620 XmlSchemaDatatype datatype
;
621 ArrayList enumeratedLiterals
;
622 string unresolvedDefault
;
623 ArrayList enumeratedNotations
;
624 DTDAttributeOccurenceType occurenceType
= DTDAttributeOccurenceType
.None
;
625 string resolvedDefaultValue
;
626 string resolvedNormalizedDefaultValue
;
628 internal DTDAttributeDefinition (DTDObjectModel root
)
638 public XmlSchemaDatatype Datatype
{
639 get { return datatype; }
640 set { datatype = value; }
643 public DTDAttributeOccurenceType OccurenceType
{
644 get { return this.occurenceType; }
645 set { this.occurenceType = value; }
648 // entity reference inside enumerated values are not allowed,
649 // but on the other hand, they are allowed inside default value.
650 // Then I decided to use string ArrayList for enumerated values,
651 // and unresolved string value for DefaultValue.
652 public ArrayList EnumeratedAttributeDeclaration
{
654 if (enumeratedLiterals
== null)
655 enumeratedLiterals
= new ArrayList ();
656 return this.enumeratedLiterals
;
660 public ArrayList EnumeratedNotations
{
662 if (enumeratedNotations
== null)
663 enumeratedNotations
= new ArrayList ();
664 return this.enumeratedNotations
;
668 public string DefaultValue
{
670 if (resolvedDefaultValue
== null)
671 resolvedDefaultValue
= ComputeDefaultValue ();
672 return resolvedDefaultValue
;
676 public string NormalizedDefaultValue
{
678 if (resolvedNormalizedDefaultValue
== null) {
679 string s
= ComputeDefaultValue ();
681 object o
= Datatype
.ParseValue (s
, null, null);
682 resolvedNormalizedDefaultValue
=
684 String
.Join (" ", (string []) o
) :
685 o
is IFormattable
? ((IFormattable
) o
).ToString (null, CultureInfo
.InvariantCulture
) : o
.ToString ();
686 } catch (Exception
) {
687 // This is for non-error-reporting reader
688 resolvedNormalizedDefaultValue
= Datatype
.Normalize (s
);
691 return resolvedNormalizedDefaultValue
;
695 public string UnresolvedDefaultValue
{
696 get { return this.unresolvedDefault; }
697 set { this.unresolvedDefault = value; }
700 public char QuoteChar
{
702 return UnresolvedDefaultValue
.Length
> 0 ?
703 this.UnresolvedDefaultValue
[0] :
708 internal string ComputeDefaultValue ()
710 if (UnresolvedDefaultValue
== null)
713 StringBuilder sb
= new StringBuilder ();
716 string value = this.UnresolvedDefaultValue
;
717 while ((next
= value.IndexOf ('&', pos
)) >= 0) {
718 int semicolon
= value.IndexOf (';', next
);
719 if (value [next
+ 1] == '#') {
720 // character reference.
721 char c
= value [next
+ 2];
722 NumberStyles style
= NumberStyles
.Integer
;
724 if (c
== 'x' || c
== 'X') {
725 spec
= value.Substring (next
+ 3, semicolon
- next
- 3);
726 style
|= NumberStyles
.HexNumber
;
729 spec
= value.Substring (next
+ 2, semicolon
- next
- 2);
730 sb
.Append ((char) int.Parse (spec
, style
, CultureInfo
.InvariantCulture
));
732 sb
.Append (value.Substring (pos
, next
- 1));
733 string name
= value.Substring (next
+ 1, semicolon
- 2);
734 int predefined
= XmlChar
.GetPredefinedEntity (name
);
736 sb
.Append (predefined
);
738 sb
.Append (Root
.ResolveEntity (name
));
742 sb
.Append (value.Substring (pos
));
744 string ret
= sb
.ToString (1, sb
.Length
- 2);
751 internal class DTDAttListDeclaration
: DTDNode
754 Hashtable attributeOrders
= new Hashtable ();
755 ArrayList attributes
= new ArrayList ();
757 internal DTDAttListDeclaration (DTDObjectModel root
)
764 set { name = value; }
767 public DTDAttributeDefinition
this [int i
] {
768 get { return Get (i); }
771 public DTDAttributeDefinition
this [string name
] {
772 get { return Get (name); }
775 public DTDAttributeDefinition
Get (int i
)
777 return attributes
[i
] as DTDAttributeDefinition
;
780 public DTDAttributeDefinition
Get (string name
)
782 object o
= attributeOrders
[name
];
784 return attributes
[(int) o
] as DTDAttributeDefinition
;
789 public IList Definitions
{
790 get { return attributes; }
793 public void Add (DTDAttributeDefinition def
)
795 if (attributeOrders
[def
.Name
] != null)
796 throw new InvalidOperationException (String
.Format (
797 "Attribute definition for {0} was already added at element {1}.",
798 def
.Name
, this.Name
));
800 attributeOrders
.Add (def
.Name
, attributes
.Count
);
801 attributes
.Add (def
);
805 get { return attributeOrders.Count; }
809 internal class DTDEntityBase
: DTDNode
815 string replacementText
;
817 Exception loadException
;
820 protected DTDEntityBase (DTDObjectModel root
)
825 internal bool IsInvalid
{
826 get { return isInvalid; }
827 set { isInvalid = value; }
830 public bool LoadFailed
{
831 get { return loadFailed; }
832 set { loadFailed = value; }
837 set { name = value; }
840 public string PublicId
{
841 get { return publicId; }
842 set { publicId = value; }
845 public string SystemId
{
846 get { return systemId; }
847 set { systemId = value; }
850 public string LiteralEntityValue
{
851 get { return literalValue; }
852 set { literalValue = value; }
855 public string ReplacementText
{
856 get { return replacementText; }
857 set { replacementText = value; }
860 public void Resolve (XmlResolver resolver
)
862 if (resolver
== null || SystemId
== null || SystemId
.Length
== 0) {
864 LiteralEntityValue
= String
.Empty
;
870 if (BaseURI
!= null && BaseURI
.Length
> 0)
871 baseUri
= new Uri (BaseURI
);
872 } catch (UriFormatException
) {
875 Uri absUri
= resolver
.ResolveUri (baseUri
, SystemId
);
876 string absPath
= absUri
.ToString ();
877 if (Root
.ExternalResources
.ContainsKey (absPath
))
878 LiteralEntityValue
= (string) Root
.ExternalResources
[absPath
];
881 s
= resolver
.GetEntity (absUri
, null, typeof (Stream
)) as Stream
;
882 XmlTextReaderImpl xtr
= new XmlTextReaderImpl (absPath
, s
, Root
.NameTable
);
883 // Don't skip Text declaration here. LiteralEntityValue contains it. See spec 4.5
884 this.BaseURI
= absPath
;
885 LiteralEntityValue
= xtr
.GetRemainder ().ReadToEnd ();
887 Root
.ExternalResources
.Add (absPath
, LiteralEntityValue
);
888 if (Root
.ExternalResources
.Count
> DTDObjectModel
.AllowedExternalEntitiesMax
)
889 throw new InvalidOperationException ("The total amount of external entities exceeded the allowed number.");
891 } catch (Exception ex
) {
893 LiteralEntityValue
= String
.Empty
;
895 // throw NotWFError ("Cannot resolve external entity. URI is " + absPath + " .");
903 internal class DTDEntityDeclaration
: DTDEntityBase
908 ArrayList ReferencingEntities
= new ArrayList ();
912 bool hasExternalReference
;
914 internal DTDEntityDeclaration (DTDObjectModel root
) : base (root
)
918 public string NotationName
{
919 get { return notationName; }
920 set { notationName = value; }
923 public bool HasExternalReference
{
926 ScanEntityValue (new ArrayList ());
927 return hasExternalReference
;
931 public string EntityValue
{
936 if (PublicId
== null && SystemId
== null && LiteralEntityValue
== null)
939 if (entityValue
== null) {
940 if (NotationName
!= null)
942 else if (SystemId
== null || SystemId
== String
.Empty
) {
943 entityValue
= ReplacementText
;
944 if (entityValue
== null)
945 entityValue
= String
.Empty
;
947 entityValue
= ReplacementText
;
949 // Check illegal recursion.
950 ScanEntityValue (new ArrayList ());
956 // It returns whether the entity contains references to external entities.
957 public void ScanEntityValue (ArrayList refs
)
959 // To modify this code, beware nesting between this and EntityValue.
960 string value = EntityValue
;
961 if (this.SystemId
!= null)
962 hasExternalReference
= true;
965 throw NotWFError ("Entity recursion was found.");
969 foreach (string referenced
in refs
)
970 if (this.ReferencingEntities
.Contains (referenced
))
971 throw NotWFError (String
.Format (
972 "Nested entity was found between {0} and {1}",
978 int len
= value.Length
;
980 for (int i
=0; i
<len
; i
++) {
988 string name
= value.Substring (start
, i
- start
);
989 if (name
.Length
== 0)
990 throw NotWFError ("Entity reference name is missing.");
992 break; // character reference
993 if (XmlChar
.GetPredefinedEntity (name
) >= 0)
994 break; // predefined reference
996 this.ReferencingEntities
.Add (name
);
997 DTDEntityDeclaration decl
= Root
.EntityDecls
[name
];
999 if (decl
.SystemId
!= null)
1000 hasExternalReference
= true;
1002 decl
.ScanEntityValue (refs
);
1003 foreach (string str
in decl
.ReferencingEntities
)
1004 ReferencingEntities
.Add (str
);
1006 value = value.Remove (start
- 1, name
.Length
+ 2);
1007 value = value.Insert (start
- 1, decl
.EntityValue
);
1008 i
-= name
.Length
+ 1; // not +2, because of immediate i++ .
1016 Root
.AddError (new XmlSchemaException ("Invalid reference character '&' is specified.",
1017 this.LineNumber
, this.LinePosition
, null, this.BaseURI
, null));
1023 internal class DTDNotationDeclaration
: DTDNode
1031 public string Name
{
1032 get { return name; }
1033 set { name = value; }
1036 public string PublicId
{
1037 get { return publicId; }
1038 set { publicId = value; }
1041 public string SystemId
{
1042 get { return systemId; }
1043 set { systemId = value; }
1046 public string LocalName
{
1047 get { return localName; }
1048 set { localName = value; }
1051 public string Prefix
{
1052 get { return prefix; }
1053 set { prefix = value; }
1056 internal DTDNotationDeclaration (DTDObjectModel root
)
1062 internal class DTDParameterEntityDeclarationCollection
1064 Hashtable peDecls
= new Hashtable ();
1065 DTDObjectModel root
;
1067 public DTDParameterEntityDeclarationCollection (DTDObjectModel root
)
1072 public DTDParameterEntityDeclaration
this [string name
] {
1073 get { return peDecls [name] as DTDParameterEntityDeclaration; }
1076 public void Add (string name
, DTDParameterEntityDeclaration decl
)
1078 // PEDecl can be overriden.
1079 if (peDecls
[name
] != null)
1081 decl
.SetRoot (root
);
1082 peDecls
.Add (name
, decl
);
1085 public ICollection Keys
{
1086 get { return peDecls.Keys; }
1089 public ICollection Values
{
1090 get { return peDecls.Values; }
1094 internal class DTDParameterEntityDeclaration
: DTDEntityBase
1096 internal DTDParameterEntityDeclaration (DTDObjectModel root
) : base (root
)
1101 internal enum DTDContentOrderType
1108 internal enum DTDAttributeOccurenceType
1116 internal enum DTDOccurence