2 using System.Collections;
6 namespace Commons.Xml.Nvdl
9 internal class NvdlFilteredXmlReader : XmlDefaultReader
11 public NvdlFilteredXmlReader (XmlReader reader,
12 NvdlValidateInterp validate)
22 public void AttachPlaceholder ()
26 public void DetachPlaceholder ()
31 internal class NvdlFilteredXmlReader : XmlReader
33 int placeHolderDepth = -1;
34 XmlNodeType nextPlaceHolder;
35 XmlNodeType placeHolder;
36 bool placeHolderLocalNameAttr;
37 Stack placeHolderDepthStack;
38 NvdlValidateInterp validate;
41 AttributeInfo [] attributes = new AttributeInfo [10];
44 // PlanAtt validation cache.
45 Hashtable attributeValidators = new Hashtable ();
49 public string LocalName;
50 public string NamespaceURI;
53 public NvdlFilteredXmlReader (XmlReader reader,
54 NvdlValidateInterp validate)
57 this.validate = validate;
60 public void AttachPlaceholder ()
62 if (placeHolderDepthStack == null)
63 placeHolderDepthStack = new Stack ();
65 placeHolderDepthStack.Push (placeHolderDepth);
66 placeHolderDepth = reader.Depth;
67 nextPlaceHolder = XmlNodeType.Element;
70 public void DetachPlaceholder ()
72 if (placeHolderDepthStack.Count > 0)
73 placeHolderDepth = (int) placeHolderDepthStack.Pop ();
75 placeHolderDepth = -1;
76 nextPlaceHolder = XmlNodeType.EndElement;
79 private void AddAttribute ()
81 if (attributes.Length == attributeCount) {
82 AttributeInfo [] newArr =
83 new AttributeInfo [attributeCount * 2];
84 Array.Copy (attributes, newArr, attributeCount);
86 AttributeInfo ai = attributes [attributeCount];
88 ai = new AttributeInfo ();
89 attributes [attributeCount] = ai;
91 ai.LocalName = reader.LocalName;
92 ai.NamespaceURI = reader.NamespaceURI;
96 private SimpleRule FindAttributeRule (string ns, SimpleMode mode)
98 SimpleRule any = null;
99 foreach (SimpleRule rule in mode.AttributeRules) {
100 if (!rule.MatchNS (ns))
108 throw new NvdlValidationException ("NVDL internal error: should not happen. No matching rule was found.", reader as IXmlLineInfo);
113 public override bool Read ()
115 // This class itself never proceeds, just checks if
116 // the reader is placed on EOF.
123 if (nextPlaceHolder != XmlNodeType.None) {
124 placeHolder = nextPlaceHolder;
125 nextPlaceHolder = XmlNodeType.None;
129 if (!reader.MoveToFirstAttribute ())
132 // Attribute rule application
133 attributeValidators.Clear ();
135 // FIXME: could be more efficient
136 SimpleRule rule = FindAttributeRule (
138 validate.CreatedMode);
139 foreach (SimpleAction a in rule.Actions) {
140 SimpleResultAction ra =
141 a as SimpleResultAction;
143 ra.ResultType == NvdlResultType.Attach)
147 attributeValidators [reader.NamespaceURI] = a;
149 } while (reader.MoveToNextAttribute ());
150 reader.MoveToElement ();
152 if (attributeValidators.Count > 0) {
153 foreach (string ns in attributeValidators.Keys) {
154 ((SimpleValidate) attributeValidators [
155 ns]).ValidateAttributes (reader, ns);
162 public override int AttributeCount {
164 switch (placeHolder) {
165 case XmlNodeType.Element:
166 case XmlNodeType.Attribute: // ns or localName attribute on placeHolder element
167 case XmlNodeType.Text: // attribute value of ns or localName attribute on placeHolder element
169 case XmlNodeType.EndElement:
172 return attributeCount;
177 public override string BaseURI {
178 get { return reader.BaseURI; }
181 public override int Depth {
183 if (placeHolderDepth < 0)
185 int basis = reader.Depth + placeHolderDepthStack.Count + 1;
186 switch (placeHolder) {
187 case XmlNodeType.Text:
189 case XmlNodeType.Attribute:
197 public override bool EOF {
198 get { return reader.EOF && placeHolder != XmlNodeType.None; }
201 public override bool HasValue {
203 switch (placeHolder) {
204 case XmlNodeType.Attribute:
205 case XmlNodeType.Text:
207 case XmlNodeType.Element:
208 case XmlNodeType.EndElement:
211 return reader.HasValue;
216 public override bool IsDefault {
218 return placeHolder == XmlNodeType.None &&
223 public override bool IsEmptyElement {
225 return placeHolder == XmlNodeType.None &&
226 reader.IsEmptyElement;
230 public override string LocalName {
232 switch (placeHolder) {
233 case XmlNodeType.Element:
234 case XmlNodeType.EndElement:
235 return "placeHolder";
236 case XmlNodeType.Attribute:
237 return placeHolderLocalNameAttr ?
239 case XmlNodeType.Text:
242 return reader.LocalName;
247 public override string Name {
249 switch (placeHolder) {
250 case XmlNodeType.Element:
251 case XmlNodeType.EndElement:
252 return "placeHolder";
253 case XmlNodeType.Attribute:
254 return placeHolderLocalNameAttr ?
256 case XmlNodeType.Text:
264 public override string NamespaceURI {
266 switch (placeHolder) {
267 case XmlNodeType.Element:
268 case XmlNodeType.EndElement:
269 return Nvdl.InstanceNamespace;
270 case XmlNodeType.Attribute:
271 return placeHolderLocalNameAttr ?
273 case XmlNodeType.Text:
276 return reader.NamespaceURI;
281 public override XmlNameTable NameTable {
282 get { return reader.NameTable; }
285 public override XmlNodeType NodeType {
287 return placeHolder != XmlNodeType.None ?
288 placeHolder : reader.NodeType;
292 public override string Prefix {
294 return placeHolder != XmlNodeType.None ?
295 String.Empty : reader.Name;
299 public override char QuoteChar {
300 get { return reader.QuoteChar; }
303 public override ReadState ReadState {
305 return placeHolder != XmlNodeType.None &&
306 reader.ReadState != ReadState.Error ?
307 ReadState.Interactive :
312 public override string Value {
314 switch (placeHolder) {
315 case XmlNodeType.Element:
316 case XmlNodeType.EndElement:
318 case XmlNodeType.Attribute:
319 case XmlNodeType.Text:
320 return placeHolderLocalNameAttr ?
329 // FIXME: xml:lang might have been filtered
330 public override string XmlLang {
331 get { return reader.XmlLang; }
334 // FIXME: xml:space might have been filtered
335 public override XmlSpace XmlSpace {
336 get { return reader.XmlSpace; }
339 public override string this [int i] {
340 get { return GetAttribute (i); }
343 public override string this [string name] {
344 get { return GetAttribute (name); }
347 public override string this [string localName, string ns] {
348 get { return GetAttribute (localName, ns); }
351 public override string GetAttribute (int i)
353 if (placeHolder == XmlNodeType.Element)
354 return placeHolderLocalNameAttr ?
355 reader.LocalName : reader.NamespaceURI;
357 return reader.GetAttribute (
358 attributes [i].LocalName,
359 attributes [i].NamespaceURI);
362 public override string GetAttribute (string name)
364 if (placeHolder == XmlNodeType.Element) {
367 return reader.LocalName;
369 return reader.NamespaceURI;
374 return reader.GetAttribute (name);
377 public override string GetAttribute (string localName, string ns)
379 if (placeHolder == XmlNodeType.Element) {
380 if (ns != String.Empty)
382 return GetAttribute (localName);
384 return reader.GetAttribute (localName, ns);
387 public override void ResolveEntity ()
389 if (placeHolder != XmlNodeType.None)
390 throw new XmlException ("Current node is not an EntityReference.");
391 reader.ResolveEntity ();
394 public override void Close ()
399 public override string LookupNamespace (string prefix)
401 // For placeHolder element, we treat them as to have
402 // empty prefix. So we have to handle empty prefix as if
403 // it was mapped to the namespace.
404 if (placeHolder != XmlNodeType.None && prefix == String.Empty)
405 return Nvdl.InstanceNamespace;
406 return reader.LookupNamespace (prefix);
409 public override bool MoveToElement ()
411 switch (placeHolder) {
412 case XmlNodeType.Element:
413 case XmlNodeType.EndElement:
415 case XmlNodeType.Attribute:
416 case XmlNodeType.Text:
417 placeHolder = XmlNodeType.Element;
418 placeHolderLocalNameAttr = false;
421 return reader.MoveToElement ();
425 public override bool MoveToFirstAttribute ()
427 switch (placeHolder) {
428 case XmlNodeType.Element:
429 placeHolder = XmlNodeType.Attribute;
430 placeHolderLocalNameAttr = true;
432 case XmlNodeType.EndElement:
434 case XmlNodeType.Attribute:
435 case XmlNodeType.Text:
436 placeHolder = XmlNodeType.Attribute;
437 placeHolderLocalNameAttr = true;
440 if (attributeCount == 0)
442 return reader.MoveToAttribute (
443 attributes [0].LocalName,
444 attributes [0].NamespaceURI);
448 public override bool MoveToNextAttribute ()
450 switch (placeHolder) {
451 case XmlNodeType.Element:
452 case XmlNodeType.EndElement:
454 case XmlNodeType.Attribute:
455 case XmlNodeType.Text:
456 if (!placeHolderLocalNameAttr)
458 placeHolderLocalNameAttr = false;
459 placeHolder = XmlNodeType.Attribute;
462 if (reader.NodeType == XmlNodeType.Element)
464 for (int i = 0; i < attributeCount - 1; i++) {
465 if (attributes [i].LocalName != reader.LocalName ||
466 attributes [i].NamespaceURI != reader.NamespaceURI)
468 reader.MoveToAttribute (
469 attributes [i + 1].LocalName,
470 attributes [i + 1].NamespaceURI);
477 public override bool ReadAttributeValue ()
479 switch (placeHolder) {
480 case XmlNodeType.Element:
481 case XmlNodeType.EndElement:
482 case XmlNodeType.Text:
484 case XmlNodeType.Attribute:
485 placeHolder = XmlNodeType.Text;
488 return reader.ReadAttributeValue ();
492 public override void MoveToAttribute (int i)
494 switch (placeHolder) {
495 case XmlNodeType.EndElement:
496 throw new IndexOutOfRangeException ();
497 case XmlNodeType.Element:
498 case XmlNodeType.Attribute:
499 case XmlNodeType.Text:
502 placeHolderLocalNameAttr = true;
505 placeHolderLocalNameAttr = false;
508 throw new IndexOutOfRangeException ();
510 if (i < 0 || attributeCount <= i)
511 throw new IndexOutOfRangeException ();
512 reader.MoveToAttribute (
513 attributes [i].LocalName,
514 attributes [i].NamespaceURI);
519 public override bool MoveToAttribute (string qname)
521 int index = qname.IndexOf (':');
523 return MoveToAttribute (qname, String.Empty);
524 return MoveToAttribute (qname.Substring (index + 1),
525 LookupNamespace (qname.Substring (0, index)));
528 public override bool MoveToAttribute (string localName, string ns)
530 switch (placeHolder) {
531 case XmlNodeType.EndElement:
533 case XmlNodeType.Element:
534 case XmlNodeType.Attribute:
535 case XmlNodeType.Text:
536 if (ns != String.Empty)
549 for (int i = 0; i < attributeCount; i++) {
550 if (attributes [i].LocalName != localName ||
551 attributes [i].NamespaceURI != ns)
553 return reader.MoveToAttribute (localName, ns);