Re: XPathResultType - помогите новичку разобраться
От: V.Petrovski Беларусь  
Дата: 06.04.04 08:15
Оценка:
Здравствуйте, Nikolay_P_I, Вы писали:

N_P>Непонятная мне ситуация — попробовал сделать, как по инструкции и получил "case 1" уже есть.


N_P>В MSDN пара строк всего (или я не так ищу?). Распечатал содержимое.


N_P>0 Number

N_P>1 String
N_P>1 Navigator
N_P>2 Boolean
N_P>3 Nodeset
N_P>5 Any
N_P>6 Error

Таблица соответсвия XSL type классам из FCL

String — System.String (XPath)
Boolean — System.Boolean (XPath)
Number — System.Double (XPath)
Result Tree Fragment — System.Xml.XPath.XPathNavigator (XSLT)
Node Set — System.Xml.XPath.XPathNodeIterator (XPath)


N_P>Что с этим делать ? Я так понимаю — "Navigator" равен то же "1". Почему ?

N_P>Я неправильно понимаю "tree fragment" как группу нод ? Почему его приравняли к String ? Чем это вообще чревато ?
В реализации XSL много вопросов, вот например на какой прикол
Автор: V.Petrovski
Дата: 23.03.04
я наткнулся.

N_P>В догонку — что КОНКРЕТНО значат позиции

А что не понятно?

N_P>Any — просто не понятно

Это когда функция может возвращать значение любого типа, или как её еще называют untyped function.
XSL Processor сам определит что за тип возвращается, вот кусок из Rotor
 if(returnedType == XPathResultType.Any) {
                // If function is untyped get returned type from real result
                returnedType = XsltCompileContext.GetXPathType(result.GetType());
        }


N_P>Error — какого рода ошибки имеются ввиду и чем они отличаются от тех ошибок, что приводят к ArgumentException при XPathNavigator.Compile(...) ?

Любой твой Exception будет обрамлен в XsltException, смотри код ниже.

N_P>Navigator — Чем он отличается от Nodeset ? Нода с цепочкой childов ?

Смотри таблицу(выше) соответсвия XSL type классам из FCL.

Вот код функции InvokeFunction класса System.Xml.XPath.XsltFunction, я думаю он тебе все прояснит. Обрати внимание на жирный фрагмент.
private void InvokeFunction(XPathNavigator qy) {
        IXsltContextFunction function = this.Function;

        // calculate arguments:
        Debug.Assert(_ArgArray != null && _ArgArray.Length == _ArgList.Count);
        for(int i = _ArgList.Count - 1; 0 <= i; i --) {
                IQuery arg = (IQuery) _ArgList[i];
                if (arg.ReturnType() == XPathResultType.NodeSet) {
                        _ArgArray[i] = new XPathQueryIterator(arg, qy.Clone());
                }
                else {
                        _ArgArray[i] = arg.getValue(qy, null);
                }
        }

        try {
                object result = function.Invoke(_XsltContext, _ArgArray, qy);

                if(result == null) {
                        _ResultQuery = new OperandQuery( String.Empty, XPathResultType.String );
                }
                else {
                        XPathResultType returnedType = function.ReturnType;
                        if(returnedType == XPathResultType.Any) {
                                // If function is untyped get returned type from real result
                                returnedType = XsltCompileContext.GetXPathType(result.GetType());
                        }
                        switch (returnedType) {
                        case XPathResultType.String :
                                // trick. As soon XPathResultType.Navigator will be distinct type rid of from it. 
                                //_ResultQuery = new OperandQuery( result, XPathResultType.String );
                                if(result is XPathNavigator) {
                                        _ResultQuery = new NavigatorQuery((XPathNavigator)result);
                                }
                                else {
                                        _ResultQuery = new OperandQuery( result, XPathResultType.String );
                                }
                                break;
                        case XPathResultType.Boolean :
                                _ResultQuery = new OperandQuery( result, XPathResultType.Boolean );
                                break;
                        case XPathResultType.Number :
                                _ResultQuery = new OperandQuery( XmlConvert.ToXPathDouble( result ), XPathResultType.Number );
                                break;
                        case XPathResultType.NodeSet :
                                if (result is ResetableIterator) {
                                        _ResultQuery = new XmlIteratorQuery((ResetableIterator)result);
                                }
                                else {
                                        Debug.Assert(false, "Unexpected type of XPathNodeIterator");
                                        throw new NotSupportedException(Res.GetString(Res.XmlUnsupportedType, result.GetType().FullName)); 
                                }
                                break;

//                  case XPathResultType.Navigator :
//                      _ResultQuery = new NavigatorQuery((XPathNavigator)result);
//                      break;

                        default :
                                _ResultQuery = new OperandQuery( result.ToString(), XPathResultType.String );
                                break;
                        }
                }
        }
        catch(Exception ex) {
                string qname = _Prefix != string.Empty ? _Prefix + ":" + _Name : _Name;
                throw new XsltException(Res.Xslt_FunctionFailed, new string[] {qname}, ex);
        }
}
... << RSDN@Home 1.1.3 stable Ночные Снайперы — Столица>>
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.