1 //------------------------------------------------------------------------------
2 // <copyright file="Stylesheet.cs" company="Microsoft">
3 // Copyright (c) Microsoft Corporation. All rights reserved.
5 // <owner current="true" primary="true">Microsoft</owner>
6 //------------------------------------------------------------------------------
8 using System.Collections.Generic;
9 using System.Diagnostics;
10 using System.Xml.Xsl.Qil;
12 namespace System.Xml.Xsl.Xslt {
14 internal class StylesheetLevel {
15 public Stylesheet[] Imports = null;
17 // If (this is Stylesheet) {
18 // ModeFlags and ApplyFunctions are abblout apply-imports
20 // ModeFlags and ApplyFunctions are abblout apply-templates
22 // mode -> FocusFlags; Used to generate and call apply-imports/apply-template functions
23 public Dictionary<QilName, XslFlags> ModeFlags = new Dictionary<QilName, XslFlags>();
24 // mode -> xsl:apply-import functions for that mode
25 public Dictionary<QilName, List<QilFunction>> ApplyFunctions = new Dictionary<QilName, List<QilFunction>>();
28 internal class Stylesheet : StylesheetLevel {
29 private Compiler compiler;
30 public List<Uri> ImportHrefs = new List<Uri>();
31 public List<XslNode> GlobalVarPars = new List<XslNode>();
33 // xsl:attribute-set/@name -> AttributeSet
34 public Dictionary<QilName, AttributeSet> AttributeSets = new Dictionary<QilName, AttributeSet>();
36 private int importPrecedence;
37 private int orderNumber = 0;
40 WhitespaceRules[0] - rules with default priority 0
41 WhitespaceRules[1] - rules with default priority -0.25
42 WhitespaceRules[2] - rules with default priority -0.5
44 public List<WhitespaceRule>[] WhitespaceRules = new List<WhitespaceRule>[3];
46 public List<Template> Templates = new List<Template>(); // Templates defined on this level. Empty for RootLevel.
47 // xsl:template/@mode -> list of @match'es
48 public Dictionary<QilName, List<TemplateMatch>> TemplateMatches = new Dictionary<QilName, List<TemplateMatch>>();
50 public void AddTemplateMatch(Template template, QilLoop filter) {
51 List<TemplateMatch> matchesForMode;
52 if (!TemplateMatches.TryGetValue(template.Mode, out matchesForMode)) {
53 matchesForMode = TemplateMatches[template.Mode] = new List<TemplateMatch>();
55 matchesForMode.Add(new TemplateMatch(template, filter));
58 public void SortTemplateMatches() {
59 foreach (QilName mode in TemplateMatches.Keys) {
60 TemplateMatches[mode].Sort(TemplateMatch.Comparer);
64 public Stylesheet(Compiler compiler, int importPrecedence) {
65 this.compiler = compiler;
66 this.importPrecedence = importPrecedence;
68 WhitespaceRules[0] = new List<WhitespaceRule>();
69 WhitespaceRules[1] = new List<WhitespaceRule>();
70 WhitespaceRules[2] = new List<WhitespaceRule>();
73 public int ImportPrecedence { get { return importPrecedence; } }
75 public void AddWhitespaceRule(int index, WhitespaceRule rule) {
76 WhitespaceRules[index].Add(rule);
79 public bool AddVarPar(VarPar var) {
80 Debug.Assert(var.NodeType == XslNodeType.Variable || var.NodeType == XslNodeType.Param);
81 Debug.Assert(var.Name.NamespaceUri != null, "Name must be resolved in XsltLoader");
82 foreach (XslNode prevVar in GlobalVarPars) {
83 if (prevVar.Name.Equals(var.Name)) {
84 // [ERR XT0630] It is a static error if a stylesheet contains more than one binding
85 // of a global variable with the same name and same import precedence, unless it also
86 // contains another binding with the same name and higher import precedence.
87 return compiler.AllGlobalVarPars.ContainsKey(var.Name);
90 GlobalVarPars.Add(var);
94 public bool AddTemplate(Template template) {
95 Debug.Assert(template.ImportPrecedence == 0);
97 template.ImportPrecedence = this.importPrecedence;
98 template.OrderNumber = this.orderNumber++;
100 compiler.AllTemplates.Add(template);
102 if (template.Name != null) {
104 if (!compiler.NamedTemplates.TryGetValue(template.Name, out old)) {
105 compiler.NamedTemplates[template.Name] = template;
107 Debug.Assert(template.ImportPrecedence <= old.ImportPrecedence, "Global objects are processed in order of decreasing import precedence");
108 if (old.ImportPrecedence == template.ImportPrecedence) {
114 if (template.Match != null) {
115 Templates.Add(template);