File: FrameworkFork\Microsoft.Xml\Xml\XPath\Internal\NodeFunctions.cs
Web Access
Project: src\src\dotnet-svcutil\lib\src\dotnet-svcutil-lib.csproj (dotnet-svcutil-lib)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
 
namespace MS.Internal.Xml.XPath
{
    using System;
    using Microsoft.Xml;
    using Microsoft.Xml.XPath;
    using System.Diagnostics;
    using System.Globalization;
    using Microsoft.Xml.Xsl;
    using FT = MS.Internal.Xml.XPath.Function.FunctionType;
 
    internal sealed class NodeFunctions : ValueQuery
    {
        private Query _arg = null;
        private FT _funcType;
        private XsltContext _xsltContext;
 
        public NodeFunctions(FT funcType, Query arg)
        {
            _funcType = funcType;
            _arg = arg;
        }
 
        public override void SetXsltContext(XsltContext context)
        {
            _xsltContext = context.Whitespace ? context : null;
            if (_arg != null)
            {
                _arg.SetXsltContext(context);
            }
        }
 
        private XPathNavigator EvaluateArg(XPathNodeIterator context)
        {
            if (_arg == null)
            {
                return context.Current;
            }
            _arg.Evaluate(context);
            return _arg.Advance();
        }
 
        public override object Evaluate(XPathNodeIterator context)
        {
            XPathNavigator argVal;
 
            switch (_funcType)
            {
                case FT.FuncPosition:
                    return (double)context.CurrentPosition;
                case FT.FuncLast:
                    return (double)context.Count;
                case FT.FuncNameSpaceUri:
                    argVal = EvaluateArg(context);
                    if (argVal != null)
                    {
                        return argVal.NamespaceURI;
                    }
                    break;
                case FT.FuncLocalName:
                    argVal = EvaluateArg(context);
                    if (argVal != null)
                    {
                        return argVal.LocalName;
                    }
                    break;
                case FT.FuncName:
                    argVal = EvaluateArg(context);
                    if (argVal != null)
                    {
                        return argVal.Name;
                    }
                    break;
                case FT.FuncCount:
                    _arg.Evaluate(context);
                    int count = 0;
                    if (_xsltContext != null)
                    {
                        XPathNavigator nav;
                        while ((nav = _arg.Advance()) != null)
                        {
                            if (nav.NodeType != XPathNodeType.Whitespace || _xsltContext.PreserveWhitespace(nav))
                            {
                                count++;
                            }
                        }
                    }
                    else
                    {
                        while (_arg.Advance() != null)
                        {
                            count++;
                        }
                    }
                    return (double)count;
            }
            return string.Empty;
        }
 
        public override XPathResultType StaticType { get { return Function.ReturnTypes[(int)_funcType]; } }
 
        public override XPathNodeIterator Clone()
        {
            NodeFunctions method = new NodeFunctions(_funcType, Clone(_arg));
            method._xsltContext = _xsltContext;
            return method;
        }
 
        public override void PrintQuery(XmlWriter w)
        {
            w.WriteStartElement(this.GetType().Name);
            w.WriteAttributeString("name", _funcType.ToString());
            if (_arg != null)
            {
                _arg.PrintQuery(w);
            }
            w.WriteEndElement();
        }
    }
}