121 lines
5.1 KiB
C#
121 lines
5.1 KiB
C#
|
//------------------------------------------------------------------------------
|
||
|
// <copyright file="Stylesheet.cs" company="Microsoft">
|
||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||
|
// </copyright>
|
||
|
// <owner current="true" primary="true">[....]</owner>
|
||
|
//------------------------------------------------------------------------------
|
||
|
|
||
|
using System.Collections.Generic;
|
||
|
using System.Diagnostics;
|
||
|
using System.Xml.Xsl.Qil;
|
||
|
|
||
|
namespace System.Xml.Xsl.Xslt {
|
||
|
|
||
|
internal class StylesheetLevel {
|
||
|
public Stylesheet[] Imports = null;
|
||
|
|
||
|
// If (this is Stylesheet) {
|
||
|
// ModeFlags and ApplyFunctions are abblout apply-imports
|
||
|
// } else {
|
||
|
// ModeFlags and ApplyFunctions are abblout apply-templates
|
||
|
// }
|
||
|
// mode -> FocusFlags; Used to generate and call apply-imports/apply-template functions
|
||
|
public Dictionary<QilName, XslFlags> ModeFlags = new Dictionary<QilName, XslFlags>();
|
||
|
// mode -> xsl:apply-import functions for that mode
|
||
|
public Dictionary<QilName, List<QilFunction>> ApplyFunctions = new Dictionary<QilName, List<QilFunction>>();
|
||
|
}
|
||
|
|
||
|
internal class Stylesheet : StylesheetLevel {
|
||
|
private Compiler compiler;
|
||
|
public List<Uri> ImportHrefs = new List<Uri>();
|
||
|
public List<XslNode> GlobalVarPars = new List<XslNode>();
|
||
|
|
||
|
// xsl:attribute-set/@name -> AttributeSet
|
||
|
public Dictionary<QilName, AttributeSet> AttributeSets = new Dictionary<QilName, AttributeSet>();
|
||
|
|
||
|
private int importPrecedence;
|
||
|
private int orderNumber = 0;
|
||
|
|
||
|
/*
|
||
|
WhitespaceRules[0] - rules with default priority 0
|
||
|
WhitespaceRules[1] - rules with default priority -0.25
|
||
|
WhitespaceRules[2] - rules with default priority -0.5
|
||
|
*/
|
||
|
public List<WhitespaceRule>[] WhitespaceRules = new List<WhitespaceRule>[3];
|
||
|
|
||
|
public List<Template> Templates = new List<Template>(); // Templates defined on this level. Empty for RootLevel.
|
||
|
// xsl:template/@mode -> list of @match'es
|
||
|
public Dictionary<QilName, List<TemplateMatch>> TemplateMatches = new Dictionary<QilName, List<TemplateMatch>>();
|
||
|
|
||
|
public void AddTemplateMatch(Template template, QilLoop filter) {
|
||
|
List<TemplateMatch> matchesForMode;
|
||
|
if (!TemplateMatches.TryGetValue(template.Mode, out matchesForMode)) {
|
||
|
matchesForMode = TemplateMatches[template.Mode] = new List<TemplateMatch>();
|
||
|
}
|
||
|
matchesForMode.Add(new TemplateMatch(template, filter));
|
||
|
}
|
||
|
|
||
|
public void SortTemplateMatches() {
|
||
|
foreach (QilName mode in TemplateMatches.Keys) {
|
||
|
TemplateMatches[mode].Sort(TemplateMatch.Comparer);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public Stylesheet(Compiler compiler, int importPrecedence) {
|
||
|
this.compiler = compiler;
|
||
|
this.importPrecedence = importPrecedence;
|
||
|
|
||
|
WhitespaceRules[0] = new List<WhitespaceRule>();
|
||
|
WhitespaceRules[1] = new List<WhitespaceRule>();
|
||
|
WhitespaceRules[2] = new List<WhitespaceRule>();
|
||
|
}
|
||
|
|
||
|
public int ImportPrecedence { get { return importPrecedence; } }
|
||
|
|
||
|
public void AddWhitespaceRule(int index, WhitespaceRule rule) {
|
||
|
WhitespaceRules[index].Add(rule);
|
||
|
}
|
||
|
|
||
|
public bool AddVarPar(VarPar var) {
|
||
|
Debug.Assert(var.NodeType == XslNodeType.Variable || var.NodeType == XslNodeType.Param);
|
||
|
Debug.Assert(var.Name.NamespaceUri != null, "Name must be resolved in XsltLoader");
|
||
|
foreach (XslNode prevVar in GlobalVarPars) {
|
||
|
if (prevVar.Name.Equals(var.Name)) {
|
||
|
// [ERR XT0630] It is a static error if a stylesheet contains more than one binding
|
||
|
// of a global variable with the same name and same import precedence, unless it also
|
||
|
// contains another binding with the same name and higher import precedence.
|
||
|
return compiler.AllGlobalVarPars.ContainsKey(var.Name);
|
||
|
}
|
||
|
}
|
||
|
GlobalVarPars.Add(var);
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
public bool AddTemplate(Template template) {
|
||
|
Debug.Assert(template.ImportPrecedence == 0);
|
||
|
|
||
|
template.ImportPrecedence = this.importPrecedence;
|
||
|
template.OrderNumber = this.orderNumber++;
|
||
|
|
||
|
compiler.AllTemplates.Add(template);
|
||
|
|
||
|
if (template.Name != null) {
|
||
|
Template old;
|
||
|
if (!compiler.NamedTemplates.TryGetValue(template.Name, out old)) {
|
||
|
compiler.NamedTemplates[template.Name] = template;
|
||
|
} else {
|
||
|
Debug.Assert(template.ImportPrecedence <= old.ImportPrecedence, "Global objects are processed in order of decreasing import precedence");
|
||
|
if (old.ImportPrecedence == template.ImportPrecedence) {
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (template.Match != null) {
|
||
|
Templates.Add(template);
|
||
|
}
|
||
|
return true;
|
||
|
}
|
||
|
}
|
||
|
}
|