/// <summary>
        /// Creates a new XPathNavigator positioned at the same node as this XPathNavigator.
        /// </summary>
        /// <returns>A new XPathNavigator positioned at the same node as this XPathNavigator.</returns>
        public override XPathNavigator Clone()
        {
            DebugEnter("Clone");
            var nav = new MacroNavigator(_macro, _nameTable, _state.Clone());

            DebugCreate(nav);
            DebugReturn("[XPathNavigator]");
            return(nav);
        }
        public void XsltDebugModeAndSortOrder(bool native, bool debug)
        {
            const string xml = @"<?xml version=""1.0"" encoding=""UTF-8""?>
<root>
    <node id=""1"" isDoc=""1"">
        <title>title-1</title>
        <node id=""3"" isDoc=""1"">
            <title>title-3</title>
            <node id=""7"" isDoc=""1"">
                <title>title-7</title>
            </node>
            <node id=""8"" isDoc=""1"">
                <title>title-8</title>
            </node>
        </node>
        <node id=""5"" isDoc=""1"">
            <title>title-5</title>
        </node>
    </node>
    <node id=""2"" isDoc=""1"">
        <title>title-2</title>
        <node id=""4"" isDoc=""1"">
            <title>title-4</title>
        </node>
        <node id=""6"" isDoc=""1"">
            <title>title-6</title>
        </node>
    </node>
</root>
";

            const string xslt = @"<?xml version=""1.0"" encoding=""UTF-8""?>
<!DOCTYPE xsl:stylesheet [
    <!ENTITY nbsp ""&#x00A0;"">
]>
<xsl:stylesheet
  version=""1.0""
  xmlns:xsl=""http://www.w3.org/1999/XSL/Transform""
  xmlns:msxml=""urn:schemas-microsoft-com:xslt""
	xmlns:umbraco.library=""urn:umbraco.library"" xmlns:Exslt.ExsltCommon=""urn:Exslt.ExsltCommon"" xmlns:Exslt.ExsltDatesAndTimes=""urn:Exslt.ExsltDatesAndTimes"" xmlns:Exslt.ExsltMath=""urn:Exslt.ExsltMath"" xmlns:Exslt.ExsltRegularExpressions=""urn:Exslt.ExsltRegularExpressions"" xmlns:Exslt.ExsltStrings=""urn:Exslt.ExsltStrings"" xmlns:Exslt.ExsltSets=""urn:Exslt.ExsltSets"" xmlns:Examine=""urn:Examine"" 
	exclude-result-prefixes=""msxml umbraco.library Exslt.ExsltCommon Exslt.ExsltDatesAndTimes Exslt.ExsltMath Exslt.ExsltRegularExpressions Exslt.ExsltStrings Exslt.ExsltSets Examine "">

    <xsl:output method=""xml"" omit-xml-declaration=""yes"" />
    <xsl:param name=""currentPage""/>

    <xsl:template match=""/"">
		<!-- <xsl:for-each select=""/root/* [@isDoc]""> -->
        <!-- <xsl:for-each select=""$currentPage/root/* [@isDoc]""> -->
        <xsl:for-each select=""/macro/nav/root/* [@isDoc]"">
<xsl:text>! </xsl:text><xsl:value-of select=""title"" /><xsl:text>
</xsl:text>
			<xsl:for-each select=""./* [@isDoc]"">
<xsl:text>!! </xsl:text><xsl:value-of select=""title"" /><xsl:text>
</xsl:text>
    			<xsl:for-each select=""./* [@isDoc]"">
<xsl:text>!!! </xsl:text><xsl:value-of select=""title"" /><xsl:text>
</xsl:text>
	    		</xsl:for-each>
			</xsl:for-each>
		</xsl:for-each>
    </xsl:template>

</xsl:stylesheet>
";
            const string expected = @"! title-1
!! title-3
!!! title-7
!!! title-8
!! title-5
! title-2
!! title-4
!! title-6
";

            // see http://www.onenaught.com/posts/352/xslt-performance-tip-dont-indent-output
            // why aren't we using an XmlWriter here?

            var transform = new XslCompiledTransform(debug);
            var xmlReader = new XmlTextReader(new StringReader(xslt))
                {
                    EntityHandling = EntityHandling.ExpandEntities
                };
            var xslResolver = new XmlUrlResolver
                {
                    Credentials = CredentialCache.DefaultCredentials
                };
            var args = new XsltArgumentList();

            // .Default is more restrictive than .TrustedXslt
            transform.Load(xmlReader, XsltSettings.Default, xslResolver);

            XPathNavigator macro;
            if (!native)
            {
                var source = new TestSource7();
                var nav = new NavigableNavigator(source);
                //args.AddParam("currentPage", string.Empty, nav.Clone());

                var x = new XmlDocument();
                x.LoadXml(xml);
                
                macro = new MacroNavigator(new[]
                {
                    // it even fails like that => macro nav. issue?
                    new MacroNavigator.MacroParameter("nav", x.CreateNavigator()) // nav.Clone())
                }
                );
            }
            else
            {
                var doc = new XmlDocument();
                doc.LoadXml("<macro />");
                var nav = doc.CreateElement("nav");
                doc.DocumentElement.AppendChild(nav);
                var x = new XmlDocument();
                x.LoadXml(xml);
                nav.AppendChild(doc.ImportNode(x.DocumentElement, true));
                macro = doc.CreateNavigator();
            }

            var writer = new StringWriter();
            transform.Transform(macro, args, writer);

            // this was working with native, debug and non-debug
            // this was working with macro nav, non-debug
            // but was NOT working (changing the order of nodes) with macro nav, debug
            // was due to an issue with macro nav IsSamePosition, fixed

            //Console.WriteLine("--------");
            //Console.WriteLine(writer.ToString());
            Assert.AreEqual(expected.Lf(), writer.ToString().Lf());
        }
        void DebugCreate(MacroNavigator nav)
        {
#if DEBUG
            Debug("Create: [MacroNavigator::{0}]", nav._uid);
#endif
        }
Esempio n. 4
0
        void DebugCreate(MacroNavigator nav)
        {
#if DEBUG
            Debug("Create: [MacroNavigator::{0}]", nav._uid);
#endif
        }
Esempio n. 5
0
 /// <summary>
 /// Creates a new XPathNavigator positioned at the same node as this XPathNavigator.
 /// </summary>
 /// <returns>A new XPathNavigator positioned at the same node as this XPathNavigator.</returns>
 public override XPathNavigator Clone()
 {
     DebugEnter("Clone");
     var nav = new MacroNavigator(_macro, _nameTable, _state.Clone());
     DebugCreate(nav);
     DebugReturn("[XPathNavigator]");
     return nav;
 }
Esempio n. 6
0
        // gets the control for the macro, using GetXsltTransform methods for execution
        // will pick XmlDocument or Navigator mode depending on the capabilities of the published caches
        internal Control LoadMacroXslt(macro macro, MacroModel model, Hashtable pageElements, bool throwError)
        {
            if (XsltFile.Trim() == string.Empty)
            {
                TraceWarn("macro", "Xslt is empty");
                return new LiteralControl(string.Empty);
            }

            using (DisposableTimer.DebugDuration<macro>("Executing XSLT: " + XsltFile))
            {
                XmlDocument macroXml = null;
                MacroNavigator macroNavigator = null;
                NavigableNavigator contentNavigator = null;

                var canNavigate =
                    UmbracoContext.Current.ContentCache.XPathNavigatorIsNavigable &&
                    UmbracoContext.Current.MediaCache.XPathNavigatorIsNavigable;

                if (!canNavigate)
                {
                     // get master xml document
                    var cache = UmbracoContext.Current.ContentCache.InnerCache as Umbraco.Web.PublishedCache.XmlPublishedCache.PublishedContentCache;
                    if (cache == null) throw new Exception("Unsupported IPublishedContentCache, only the Xml one is supported.");
                    XmlDocument umbracoXml = cache.GetXml(UmbracoContext.Current, UmbracoContext.Current.InPreviewMode);
                    macroXml = new XmlDocument();
                    macroXml.LoadXml("<macro/>");
                    foreach (var prop in macro.Model.Properties)
                    {
                        AddMacroXmlNode(umbracoXml, macroXml, prop.Key, prop.Type, prop.Value);
                    }
                }
                else
                {
                    var parameters = new List<MacroNavigator.MacroParameter>();
                    contentNavigator = UmbracoContext.Current.ContentCache.GetXPathNavigator() as NavigableNavigator;
                    var mediaNavigator = UmbracoContext.Current.MediaCache.GetXPathNavigator() as NavigableNavigator;
                    foreach (var prop in macro.Model.Properties)
                    {
                        AddMacroParameter(parameters, contentNavigator, mediaNavigator, prop.Key, prop.Type, prop.Value);
                    }
                    macroNavigator = new MacroNavigator(parameters);
                }

                if (HttpContext.Current.Request.QueryString["umbDebug"] != null && GlobalSettings.DebugMode)
                {
                    var outerXml = macroXml == null ? macroNavigator.OuterXml : macroXml.OuterXml;
                    return
                        new LiteralControl("<div style=\"border: 2px solid green; padding: 5px;\"><b>Debug from " +
                                           macro.Name +
                                           "</b><br/><p>" + HttpContext.Current.Server.HtmlEncode(outerXml) +
                                           "</p></div>");
                }

                try
                {
                    var xsltFile = getXslt(XsltFile);

                    using (DisposableTimer.DebugDuration<macro>("Performing transformation"))
                    {
                        try
                        {
                        var transformed = canNavigate
                            ? GetXsltTransformResult(macroNavigator, contentNavigator, xsltFile) // better?
                            : GetXsltTransformResult(macroXml, xsltFile); // document
                            var result = CreateControlsFromText(transformed);

                            return result;
                        }
                        catch (Exception e)
                        {
                            Exceptions.Add(e);
                            LogHelper.WarnWithException<macro>("Error parsing XSLT file", e);
                            
                            var macroErrorEventArgs = new MacroErrorEventArgs { Name = Model.Name, Alias = Model.Alias, ItemKey = Model.Xslt, Exception = e, Behaviour = UmbracoSettings.MacroErrorBehaviour };
                            var macroControl = GetControlForErrorBehavior("Error parsing XSLT file: \\xslt\\" + XsltFile, macroErrorEventArgs);
                            //if it is null, then we are supposed to throw the (original) exception
                            // see: http://issues.umbraco.org/issue/U4-497 at the end
                            if (macroControl == null && throwError)
                            {
                                throw;
                            }
                            return macroControl;
                        }   
                    }                    
                }
                catch (Exception e)
                {
                    Exceptions.Add(e);
                    LogHelper.WarnWithException<macro>("Error loading XSLT " + Model.Xslt, true, e);

                    // Invoke any error handlers for this macro
                    var macroErrorEventArgs = new MacroErrorEventArgs { Name = Model.Name, Alias = Model.Alias, ItemKey = Model.Xslt, Exception = e, Behaviour = UmbracoSettings.MacroErrorBehaviour };
                    var macroControl = GetControlForErrorBehavior("Error reading XSLT file: \\xslt\\" + XsltFile, macroErrorEventArgs);
                    //if it is null, then we are supposed to throw the (original) exception
                    // see: http://issues.umbraco.org/issue/U4-497 at the end
                    if (macroControl == null && throwError)
                    {
                        throw;
                    }
                    return macroControl;
                }
            }            
        }