2004-04-24 Atsushi Enomoto <atsushi@ximian.com>
[mono.git] / mcs / class / System.XML / Mono.Xml.Xsl / XslAttributeSet.cs
1 //
2 // XslAttributeSet.cs
3 //
4 // Authors:
5 //      Ben Maurer (bmaurer@users.sourceforge.net)
6 //      Atsushi Enomoto (ginga@kit.hi-ho.ne.jp)
7 //      
8 // (C) 2003 Ben Maurer
9 // (C) 2003 Atsushi Enomoto
10 //
11
12 using System;
13 using System.Collections;
14 using System.Collections.Specialized;
15 using System.Xml;
16 using System.Xml.Schema;
17 using System.Xml.XPath;
18 using System.Xml.Xsl;
19 using Mono.Xml.Xsl.Operations;
20
21 using QName = System.Xml.XmlQualifiedName;
22
23 namespace Mono.Xml.Xsl {
24         internal class XslAttributeSet : XslCompiledElement {
25                 QName name;
26                 // [QName]=>XslAttributeSet
27                 ArrayList usedAttributeSets = new ArrayList ();
28                 
29                 // [QName]=>XslAttribute
30                 ArrayList attributes = new ArrayList ();
31                 
32                 public XslAttributeSet (Compiler c) : base (c) {}
33                 
34                 public QName Name {
35                         get { return name; }
36                 }
37
38                 protected override void Compile (Compiler c)
39                 {
40                         this.name = c.ParseQNameAttribute ("name");
41                         
42                         QName [] attrSets = c.ParseQNameListAttribute ("use-attribute-sets");
43                         if (attrSets != null)
44                                 foreach (QName q in attrSets)
45                                         usedAttributeSets.Add (q);
46
47                         
48                         if (!c.Input.MoveToFirstChild ()) return;
49                                 
50                         do {
51                                 switch (c.Input.NodeType) {
52                                 case XPathNodeType.Element:
53                                         break;
54                                 case XPathNodeType.Whitespace:
55                                         continue;
56                                 default:
57                                         if (c.CurrentStylesheet.Version == "1.0")
58                                                 throw new XsltCompileException ("Content " + c.Input.NodeType + " is not allowed in XSLT attribute-set element.", null, c.Input);
59                                         break;
60                                 }
61                                         
62                                 if (c.Input.NamespaceURI != XsltNamespace || c.Input.LocalName != "attribute")
63                                         throw new XsltCompileException ("Invalid attr set content", null, c.Input);
64                                 attributes.Add (new XslAttribute (c));
65                         } while (c.Input.MoveToNext ());
66                         
67                         c.Input.MoveToParent ();
68                         
69                 }
70                 
71                 public void Merge (XslAttributeSet s)
72                 {
73                         attributes.AddRange (s.attributes);
74                         
75                         foreach (QName q in s.usedAttributeSets)
76                                 if (!usedAttributeSets.Contains (q))
77                                         usedAttributeSets.Add (q);
78                 }
79                 
80                 public override void Evaluate (XslTransformProcessor p) {
81                         p.SetBusy (this);
82                         
83                         if (usedAttributeSets != null) {
84                                 for (int i = 0; i < usedAttributeSets.Count; i++) {
85                                         QName set = (QName) usedAttributeSets [i];
86                                         XslAttributeSet s = p.ResolveAttributeSet (set);
87                                         if (s == null)
88                                                 throw new XsltException ("Could not resolve attribute set", null, p.CurrentNode);
89                                         
90                                         if (p.IsBusy (s))
91                                                 throw new XsltException ("circular dependency", null, p.CurrentNode);
92                                         
93                                         s.Evaluate (p);
94                                 }
95                         }
96                                                 
97                         for (int i = 0; i < attributes.Count; i++)
98                                 ((XslAttribute) attributes [i]).Evaluate (p);
99                         
100                         p.SetFree (this);
101                 }
102         }
103 }