Example #1
0
        public ContextInfo GetAttributes(XsltAttribute[] attributes)
        {
            Debug.Assert(NodeType == XmlNodeType.Element);
            Debug.Assert(attributes.Length <= _xsltAttributeNumber.Length);
            _attributes = attributes;
            // temp hack to fix value? = new AttValue(records[values[?]].value);
            _records[0].value = null;

            // Standard Attributes:
            int attExtension = 0;
            int attExclude   = 0;
            int attNamespace = 0;
            int attCollation = 0;
            int attUseWhen   = 0;

            bool isXslOutput = IsXsltNamespace() && IsKeyword(_atoms.Output);
            bool SS          = IsXsltNamespace() && (IsKeyword(_atoms.Stylesheet) || IsKeyword(_atoms.Transform));
            bool V2          = _compiler.Version == 2;

            for (int i = 0; i < attributes.Length; i++)
            {
                _xsltAttributeNumber[i] = 0;
            }

            _compiler.EnterForwardsCompatible();
            if (SS || V2 && !isXslOutput)
            {
                for (int i = 1; MoveToAttributeBase(i); i++)
                {
                    if (IsNullNamespace() && IsKeyword(_atoms.Version))
                    {
                        SetVersion(i);
                        break;
                    }
                }
            }
            if (_compiler.Version == 0)
            {
                Debug.Assert(SS, "First we parse xsl:stylesheet element");
#if XSLT2
                SetVersion(2.0);
#else
                SetVersion(1.0);
#endif
            }
            V2 = _compiler.Version == 2;
            int OptOrReq = V2 ? XsltLoader.V2Opt | XsltLoader.V2Req : XsltLoader.V1Opt | XsltLoader.V1Req;

            for (int attNum = 1; MoveToAttributeBase(attNum); attNum++)
            {
                if (IsNullNamespace())
                {
                    string localName = LocalName;
                    int    kwd;
                    for (kwd = 0; kwd < attributes.Length; kwd++)
                    {
                        if (Ref.Equal(localName, attributes[kwd].name) && (attributes[kwd].flags & OptOrReq) != 0)
                        {
                            _xsltAttributeNumber[kwd] = attNum;
                            break;
                        }
                    }

                    if (kwd == attributes.Length)
                    {
                        if (Ref.Equal(localName, _atoms.ExcludeResultPrefixes) && (SS || V2))
                        {
                            attExclude = attNum;
                        }
                        else
                        if (Ref.Equal(localName, _atoms.ExtensionElementPrefixes) && (SS || V2))
                        {
                            attExtension = attNum;
                        }
                        else
                        if (Ref.Equal(localName, _atoms.XPathDefaultNamespace) && (V2))
                        {
                            attNamespace = attNum;
                        }
                        else
                        if (Ref.Equal(localName, _atoms.DefaultCollation) && (V2))
                        {
                            attCollation = attNum;
                        }
                        else
                        if (Ref.Equal(localName, _atoms.UseWhen) && (V2))
                        {
                            attUseWhen = attNum;
                        }
                        else
                        {
                            ReportError(/*[XT0090]*/ SR.Xslt_InvalidAttribute, QualifiedName, _records[0].QualifiedName);
                        }
                    }
                }
                else if (IsXsltNamespace())
                {
                    ReportError(/*[XT0090]*/ SR.Xslt_InvalidAttribute, QualifiedName, _records[0].QualifiedName);
                }
                else
                {
                    // Ignore the attribute.
                    // 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'.
                }
            }

            _attributesRead = true;

            // 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);

            InsertExNamespaces(attExtension, _ctxInfo, /*extensions:*/ true);
            InsertExNamespaces(attExclude, _ctxInfo, /*extensions:*/ false);
            SetXPathDefaultNamespace(attNamespace);
            SetDefaultCollation(attCollation);
            if (attUseWhen != 0)
            {
                ReportNYI(_atoms.UseWhen);
            }

            MoveToElement();
            // Report missing mandatory attributes
            for (int i = 0; i < attributes.Length; i++)
            {
                if (_xsltAttributeNumber[i] == 0)
                {
                    int flags = attributes[i].flags;
                    if (
                        _compiler.Version == 2 && (flags & XsltLoader.V2Req) != 0 ||
                        _compiler.Version == 1 && (flags & XsltLoader.V1Req) != 0 && (!ForwardCompatibility || (flags & XsltLoader.V2Req) != 0)
                        )
                    {
                        ReportError(/*[XT_001]*/ SR.Xslt_MissingAttribute, attributes[i].name);
                    }
                }
            }

            return(_ctxInfo);
        }