Пример #1
0
        protected virtual ParsedTemplate PrepareTemplate(TemplateData templateData)
        {
            // clone orig doc
            XDocument workingDoc = new XDocument(this._templateDefinition);

            // start by loading any parameters as they are needed for meta-template evaluation

            Dictionary<string, XPathVariable> globalParams = new Dictionary<string, XPathVariable>();

            XElement[] paramNodes = workingDoc.Root.Elements("parameter").ToArray();
            foreach (XElement paramNode in paramNodes)
            {
                var tmplVar = new XPathVariable
                                  {
                                      Name = paramNode.Attribute("name").Value,
                                      ValueExpression =
                                          paramNode.Attribute("select") == null
                                              ? null
                                              : paramNode.Attribute("select").Value,
                                  };
                globalParams.Add(tmplVar.Name, tmplVar);
            }


            CustomXsltContext customContext = new CustomXsltContext();
            Func<string, object> onFailedResolve =
                s =>
                {
                    throw new InvalidOperationException(
                        String.Format("Parameter '{0}' could not be resolved.", s));
                };

            customContext.OnResolveVariable +=
                s =>
                {
                    XPathVariable var;

                    // if it's defined
                    if (globalParams.TryGetValue(s, out var))
                    {
                        // see if the user provided a value
                        object value;
                        if (templateData.Arguments.TryGetValue(s, out value))
                            return value;

                        // evaluate default value
                        if (!String.IsNullOrWhiteSpace(var.ValueExpression))
                            return workingDoc.XPathEvaluate(var.ValueExpression,
                                                            customContext);
                    }

                    return onFailedResolve(s);
                };

            // check for meta-template directives and expand
            XElement metaNode = workingDoc.Root.Elements("meta-template").FirstOrDefault();

            // we're going to need this later
            XmlFileProviderResolver fileResolver = new XmlFileProviderResolver(this._fileProvider, this._basePath);

            while (metaNode != null)
            {
                if (EvalCondition(customContext, metaNode, this.GetAttributeValueOrDefault(metaNode, "condition")))
                {
                    #region Debug conditional

#if DEBUG
                    const bool debugEnabled = true;
#else
                    const bool debugEnabled = false;
#endif

                    #endregion

                    XslCompiledTransform metaTransform = this.LoadStylesheet(metaNode.Attribute("stylesheet").Value);

                    XsltArgumentList xsltArgList = new XsltArgumentList();

                    // TODO this is a quick fix/hack
                    xsltArgList.AddExtensionObject("urn:lostdoc-core", new TemplateXsltExtensions(null, null));

                    var metaParamNodes = metaNode.Elements("with-param");

                    foreach (XElement paramNode in metaParamNodes)
                    {
                        string pName = paramNode.Attribute("name").Value;
                        string pExpr = paramNode.Attribute("select").Value;

                        xsltArgList.AddParam(pName,
                                             string.Empty,
                                             workingDoc.XPathEvaluate(pExpr, customContext));
                    }

                    XDocument outputDoc = new XDocument();
                    using (XmlWriter outputWriter = outputDoc.CreateWriter())
                    {
                        metaTransform.Transform(workingDoc.CreateNavigator(),
                                                xsltArgList,
                                                outputWriter,
                                                fileResolver);
                    }


                    TraceSources.TemplateSource.TraceVerbose("Template after transformation by {0}",
                                                             metaNode.Attribute("stylesheet").Value);

                    TraceSources.TemplateSource.TraceData(TraceEventType.Verbose, 1, outputDoc.CreateNavigator());

                    workingDoc = outputDoc;
                }
                else
                {
                    // didn't process, so remove it
                    metaNode.Remove();
                }


                // select next template
                metaNode = workingDoc.Root.Elements("meta-template").FirstOrDefault();
            }

            // loading template
            List<Stylesheet> stylesheets = new List<Stylesheet>();
            List<Resource> resources = new List<Resource>();
            List<Index> indices = new List<Index>();
            foreach (XElement elem in workingDoc.Root.Elements())
            {
                // we alread proessed the parameters
                if (elem.Name.LocalName == "parameter")
                    continue;

                if (elem.Name.LocalName == "apply-stylesheet")
                {
                    stylesheets.Add(this.ParseStylesheet(stylesheets, elem));
                }
                else if (elem.Name.LocalName == "index")
                {
                    indices.Add(this.ParseIndex(elem));
                }
                else if (elem.Name.LocalName == "include-resource")
                {
                    resources.Add(new Resource
                                      {
                                          Path = elem.Attribute("path").Value,
                                          ConditionExpression = this.GetAttributeValueOrDefault(elem, "condition")
                                      });
                }
                else
                {
                    throw new Exception("Unknown element: " + elem.Name.LocalName);
                }
            }

            return new ParsedTemplate
                       {
                           Resources = resources.ToArray(),
                           Stylesheets = stylesheets.ToArray(),
                           Indices = indices.ToArray()
                       };
        }
Пример #2
0
        /// <summary>
        /// The load stylesheet.
        /// </summary>
        /// <param name="name">
        /// </param>
        /// <returns>
        /// </returns>
        private XslCompiledTransform LoadStylesheet(string name)
        {
            XslCompiledTransform ret = new XslCompiledTransform(true);
            using (Stream str = this._fileProvider.OpenFile(Path.Combine(this._basePath, name)))
            {
                XmlReader reader = XmlReader.Create(str, new XmlReaderSettings { CloseInput = true, });
                XsltSettings settings = new XsltSettings(false, true);
                XmlResolver resolver = new XmlFileProviderResolver(this._fileProvider, this._basePath);
                ret.Load(reader, settings, resolver);
            }

            return ret;
        }