2004-01-14 Atsushi Enomoto <atsushi@ximian.com>
[mono.git] / mcs / class / System.XML / Mono.Xml.Schema / XsdKeyTable.cs
1 //
2 // Mono.Xml.Schema.XsdKeyTable.cs
3 //
4 // Author:
5 //      Atsushi Enomoto (ginga@kit.hi-ho.ne.jp)
6 //
7 //      (C)2003 Atsushi Enomoto
8 //
9 using System;\r
10 using System.Collections;\r
11 using System.Collections.Specialized;\r
12 using System.Xml;\r
13 using System.Xml.Schema;\r
14 \r
15 namespace Mono.Xml.Schema\r
16 {\r
17         // Created per constraining element.\r
18         public class XsdKeyTable\r
19         {\r
20                 private XsdIdentitySelector selector;\r
21                 private XmlSchemaIdentityConstraint source;\r
22                 private XmlQualifiedName qname;\r
23                 private XmlQualifiedName refKeyName;\r
24 \r
25                 public ArrayList Entries = new ArrayList ();\r
26                 public ArrayList FinishedEntries = new ArrayList ();\r
27 \r
28                 public int StartDepth;\r
29                 public XsdKeyTable ReferencedKey;\r
30 \r
31                 public XsdKeyTable (XmlSchemaIdentityConstraint source, XmlReader reader)\r
32                 {\r
33                         Reset (source, reader);\r
34                 }\r
35 \r
36                 public XmlQualifiedName QualifiedName {\r
37                         get { return qname; }\r
38                 }\r
39 \r
40                 public XmlQualifiedName RefKeyName {\r
41                         get { return refKeyName; }\r
42                 }\r
43 \r
44                 public XmlSchemaIdentityConstraint SourceSchemaIdentity {\r
45                         get { return source; }\r
46                 }\r
47 \r
48                 public XsdIdentitySelector Selector {\r
49                         get { return selector; }\r
50                 }\r
51 \r
52                 public void Reset (XmlSchemaIdentityConstraint source, XmlReader reader)\r
53                 {\r
54                         this.source = source;\r
55                         this.selector = source.CompiledSelector;\r
56                         this.qname = source.QualifiedName;\r
57                         XmlSchemaKeyref kr = source as XmlSchemaKeyref;\r
58                         if (kr != null)\r
59                                 this.refKeyName = kr.Refer;\r
60                         StartDepth = 0;\r
61                 }\r
62 \r
63                 // In this method, attributes are ignored.\r
64                 public XsdIdentityPath SelectorMatches (ArrayList qnameStack, XmlReader reader)\r
65                 {\r
66                         foreach (XsdIdentityPath path in Selector.Paths) {\r
67                                 // Only "." hits.\r
68                                 if (reader.Depth == this.StartDepth) {\r
69                                         if (path.OrderedSteps.Length == 0)\r
70                                                 return path;\r
71                                         else\r
72                                                 continue;\r
73                                 }\r
74                                 // It does not hit as yet (too shallow to hit).\r
75                                 if (reader.Depth - this.StartDepth < path.OrderedSteps.Length - 1)\r
76                                         continue;\r
77 \r
78                                 int iter = path.OrderedSteps.Length;\r
79                                 if (path.OrderedSteps [iter-1].IsAttribute)\r
80                                         iter--;\r
81 \r
82                                 if (path.Descendants && reader.Depth < this.StartDepth + iter)\r
83                                         continue;\r
84                                 else if (!path.Descendants && reader.Depth != this.StartDepth + iter)\r
85                                         continue;\r
86 \r
87                                 iter--;\r
88 \r
89                                 XsdIdentityStep step;\r
90                                 for (int x = 0; x <= iter; x++, iter--) {\r
91                                         step = path.OrderedSteps [iter - x];\r
92                                         if (step.IsAnyName)\r
93                                                 continue;\r
94                                         XmlQualifiedName qname = (XmlQualifiedName) qnameStack [qnameStack.Count - x - 1];\r
95                                         if (step.NsName != null && qname.Namespace == step.NsName)\r
96                                                 continue;\r
97                                         if (step.Name == qname.Name && step.Namespace == qname.Namespace)\r
98                                                 continue;\r
99                                         else\r
100                                                 break;\r
101                                 }\r
102                                 if (iter >= 0)  // i.e. did not match against the path.\r
103                                         continue;\r
104                                 return path;\r
105                         }\r
106                         return null;\r
107                 }\r
108         }\r
109 }\r