Ejemplo n.º 1
0
        public bool FindStylesheetElement()
        {
            if (!_topLevelReader)
            {
                if (_reader.ReadState != ReadState.Interactive)
                {
                    return(false);
                }
            }

            // The stylesheet may be an embedded stylesheet. If this is the case the reader will be in Interactive state and should be
            // positioned on xsl:stylesheet element (or any preceding whitespace) but there also can be namespaces defined on one
            // of the ancestor nodes. These namespace definitions have to be copied to the xsl:stylesheet element scope. Otherwise it
            // will not be possible to resolve them later and loading the stylesheet will end up with throwing an exception.
            IDictionary <string, string> namespacesInScope = null;

            if (_reader.ReadState == ReadState.Interactive)
            {
                // This may be an embedded stylesheet - store namespaces in scope
                IXmlNamespaceResolver nsResolver = _reader as IXmlNamespaceResolver;
                if (nsResolver != null)
                {
                    namespacesInScope = nsResolver.GetNamespacesInScope(XmlNamespaceScope.ExcludeXml);
                }
            }

            while (MoveToNextSibling() && _nodeType == XmlNodeType.Whitespace)
            {
                ;
            }

            // An Element node was reached. Potentially this is xsl:stylesheet instruction.
            if (_nodeType == XmlNodeType.Element)
            {
                // If namespacesInScope is not null then the stylesheet being read is an embedded stylesheet that can have namespaces
                // defined outside of xsl:stylesheet instruction. In this case the namespace definitions collected above have to be added
                // to the element scope.
                if (namespacesInScope != null)
                {
                    foreach (KeyValuePair <string, string> prefixNamespacePair in namespacesInScope)
                    {
                        // The namespace could be redefined on the element we just read. If this is the case scopeManager already has
                        // namespace definition for this prefix and the old definition must not be added to the scope.
                        if (_scopeManager.LookupNamespace(prefixNamespacePair.Key) == null)
                        {
                            string nsAtomizedValue = _atoms.NameTable.Add(prefixNamespacePair.Value);
                            _scopeManager.AddNsDeclaration(prefixNamespacePair.Key, nsAtomizedValue);
                            _ctxInfo.AddNamespace(prefixNamespacePair.Key, nsAtomizedValue);
                        }
                    }
                }

                // return true to indicate that we reached XmlNodeType.Element node - potentially xsl:stylesheet element.
                return(true);
            }

            // return false to indicate that we did not reach XmlNodeType.Element node so it is not a valid stylesheet.
            return(false);
        }
Ejemplo n.º 2
0
        public ContextInfo GetAttributes(int required, int number, string[] names, string[] values)
        {
            Debug.Assert(reader.NodeType == XmlNodeType.Element);
            for (int i = 0; i < number; i++)
            {
                values[i] = null;
            }
            string      elementName = QualifiedName;
            ContextInfo ctxInfo     = new ContextInfo(this);

            compiler.EnterForwardsCompatible();

            while (MoveToNextAttOrNs())
            {
                if (nodeType == XPathNodeType.Namespace)
                {
                    ctxInfo.AddNamespace(this);
                    continue;
                }
                Debug.Assert(nodeType == XPathNodeType.Attribute);
                ctxInfo.AddAttribute(this);
                bool found = false;
                for (int i = 0; i < number; i++)
                {
                    if (IsXsltAttribute(names[i]))
                    {
                        found     = true;
                        values[i] = Value;

                        // There are only two XSL elements, xsl:stylesheet/xsl:transform and xsl:output, capable
                        // of having 'version' attribute.  And only for the first one this attribute is required.
                        if (Ref.Equal(names[i], Atoms.Version) && i < required)
                        {
                            SetVersion(Value, Atoms.Version);
                        }
                        break;
                    }
                }
                if (!found)
                {
                    // An element from the XSLT namespace may have any attribute not from the XSLT namespace,
                    // provided that the expanded-name of the attribute has a non-null namespace URI.
                    // For example, it may be 'xml:space'.
                    if (IsNullNamespace() || IsXsltNamespace())
                    {
                        ReportError(/*[XT0090]*/ Res.Xslt_InvalidAttribute, QualifiedName, elementName);
                    }
                }
            }

            // Ignore invalid attributes if forwards-compatible behavior is enabled. Note that invalid
            // attributes may encounter before ForwardCompatibility flag is set to true. For example,
            // <xsl:stylesheet unknown="foo" version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"/>
            compiler.ExitForwardsCompatible(ForwardCompatibility);

            // Report missing mandatory attributes
            for (int i = 0; i < required; i++)
            {
                if (values[i] == null)
                {
                    ReportError(/*[XT_001]*/ Res.Xslt_MissingAttribute, names[i]);
                }
            }
            ctxInfo.Finish(this);
            return(ctxInfo);
        }
Ejemplo n.º 3
0
        // http://www.w3.org/TR/xslt#literal-result-element
        private XslNode LoadLiteralResultElement(bool asStylesheet) {
            Debug.Assert(input.NodeType == XPathNodeType.Element);
            string prefix   = input.Prefix;
            string name     = input.LocalName;
            string nsUri    = input.NamespaceUri;

            string version      = null;
            string extPrefixes  = null;
            string exclPrefixes = null;
            string useAttrSets  = null;
            string versionQName = null;

            List<XslNode> content = new List<XslNode>();
            ContextInfo ctxInfo = new ContextInfo(input);

            /* Process literal attributes */
            while (input.MoveToNextAttOrNs()) {
                if (input.NodeType == XPathNodeType.Namespace) {
                    ctxInfo.AddNamespace(input);
                } else {
                    Debug.Assert(input.NodeType == XPathNodeType.Attribute);
                    ctxInfo.AddAttribute(input);
                    if (input.IsXsltNamespace()) {
                        if (input.LocalName == input.Atoms.Version) {
                            version = input.Value;
                            versionQName = input.QualifiedName;
                        } else if (input.LocalName == input.Atoms.ExtensionElementPrefixes) {
                            extPrefixes = input.Value;
                        } else if (input.LocalName == input.Atoms.ExcludeResultPrefixes) {
                            exclPrefixes = input.Value;
                        } else if (input.LocalName == input.Atoms.UseAttributeSets) {
                            useAttrSets = input.Value;
                        } else {
                            // just ignore it
                        }
                    } else {
                        XslNode att = f.LiteralAttribute(f.QName(input.LocalName, input.NamespaceUri, input.Prefix), input.Value, input.XslVersion);
                        // QilGenerator takes care of AVTs, and needs line info
                        AddInstruction(content, SetLineInfo(att, ctxInfo.lineInfo));
                    }
                }
            }
            ctxInfo.Finish(input);

            if (version != null) {
                // Enable forwards-compatible behavior if version attribute is not "1.0"
                input.SetVersion(version, versionQName);
            } else {
                if (asStylesheet) {
                    if (Ref.Equal(nsUri, input.Atoms.UriWdXsl) && Ref.Equal(name, input.Atoms.Stylesheet)) {
                        ReportError(/*[XT_025]*/Res.Xslt_WdXslNamespace);
                    } else {
                        ReportError(/*[XT0150]*/Res.Xslt_WrongStylesheetElement);
                    }
                    input.SkipNode();
                    return null;
                }
            }

            // Parse xsl:extension-element-prefixes attribute (now that forwards-compatible mode is known)
            InsertExNamespaces(extPrefixes, ref ctxInfo.nsList, /*extensions:*/true);

            XslNode result;

            // Now we can determine whether this element is an extension element (spec section 14.1)
            if (input.IsExtensionNamespace(nsUri)) {
                // This is not a literal result element, so drop all attributes we have collected
                content = LoadFallbacks(name);
                result = f.List();
            } else {
                // Parse xsl:exclude-result-prefixes attribute (now that it's known this is a literal result element)
                InsertExNamespaces(exclPrefixes, ref ctxInfo.nsList, /*extensions:*/false);

                // Insert all attribute sets at the beginning of content
                content.InsertRange(0, ParseUseAttributeSets(useAttrSets, ctxInfo.lineInfo));

                content = LoadEndTag(LoadInstructions(content));
                result = f.LiteralElement(f.QName(name, nsUri, prefix));
            }

            return SetInfo(result, content, ctxInfo);
        }
Ejemplo n.º 4
0
        public ContextInfo GetAttributes(int required, int number, string[] names, string[] values) {
            Debug.Assert(reader.NodeType == XmlNodeType.Element);
            for (int i = 0; i < number; i ++) {
                values[i] = null;
            }
            string elementName = QualifiedName;
            ContextInfo ctxInfo = new ContextInfo(this);
            compiler.EnterForwardsCompatible();

            while (MoveToNextAttOrNs()) {
                if (nodeType == XPathNodeType.Namespace) {
                    ctxInfo.AddNamespace(this);
                    continue;
                }
                Debug.Assert(nodeType == XPathNodeType.Attribute);
                ctxInfo.AddAttribute(this);
                bool found = false;
                for (int i = 0; i < number; i ++) {
                    if (IsXsltAttribute(names[i])) {
                        found = true;
                        values[i] = Value;

                        // There are only two XSL elements, xsl:stylesheet/xsl:transform and xsl:output, capable
                        // of having 'version' attribute.  And only for the first one this attribute is required.
                        if (Ref.Equal(names[i], Atoms.Version) && i < required) {
                            SetVersion(Value, Atoms.Version);
                        }
                        break;
                    }
                }
                if (!found) {
                    // An element from the XSLT namespace may have any attribute not from the XSLT namespace,
                    // provided that the expanded-name of the attribute has a non-null namespace URI.
                    // For example, it may be 'xml:space'.
                    if (IsNullNamespace() || IsXsltNamespace()) {
                        ReportError(/*[XT0090]*/Res.Xslt_InvalidAttribute, QualifiedName, elementName);
                    }
                }
            }

            // Ignore invalid attributes if forwards-compatible behavior is enabled. Note that invalid
            // attributes may encounter before ForwardCompatibility flag is set to true. For example,
            // <xsl:stylesheet unknown="foo" version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"/>
            compiler.ExitForwardsCompatible(ForwardCompatibility);

            // Report missing mandatory attributes
            for (int i = 0; i < required; i ++) {
                if (values[i] == null) {
                    ReportError(/*[XT_001]*/Res.Xslt_MissingAttribute, names[i]);
                }
            }
            ctxInfo.Finish(this);
            return ctxInfo;
        }