Ejemplo n.º 1
0
        /// <copydocfrom cref="IXmlMapper{T, D}.Map(T, string, string, bool)" />
        public TDestination Map(XPathProcessor source, string nodeName, string xmlNamespace = "", bool outputDefault = false)
        {
            RegisterNamespace(source, NamespacePrefix, Namespace);

            // Push both the node and the namespace - presumption that the namespace applies to the node
            source.Push(nodeName, Namespace);
            try
            {
                if (!source.CurrentNode())
                {
                    return(null);
                }

                RegisterNamespace(source, XsiPrefix, XsiNamespace);
                var xmlType = source.ToString("type", XsiPrefix, isAttribute: true);

                TDestination destination;

                // This mapper can handle it if there's no type specified or it's our type
                if (string.IsNullOrEmpty(xmlType) || string.IsNullOrEmpty(XmlType))
                {
                    destination = CreateAndMap(source);
                }
                else
                {
                    var t = XmlTypeInfo(source, xmlType);
                    if (XmlTypeNamespace == t.Item1 && XmlType == t.Item2)
                    {
                        destination = CreateAndMap(source);
                    }
                    else
                    {
                        // Otherwise, pass off to the engine
                        // NB Use the current namespace for the node name, not the target mapper's
                        if (!nodeName.Contains(":"))
                        {
                            nodeName = string.Format("{0}:{1}", NamespacePrefix, nodeName);
                        }

                        try
                        {
                            destination = Engine.Map <XPathProcessor, TDestination>(source, nodeName, t.Item1, t.Item2);
                        }
                        catch (XmlTypeMappingException)
                        {
                            // try to map with our base engine
                            destination = this.CreateAndMap(source);
                        }
                    }
                }

                return(destination);
            }
            finally
            {
                // Make sure we unwind the stack in all cases
                source.Pop();
            }
        }
Ejemplo n.º 2
0
        protected TDestination Map(XPathProcessor source, string nodeName, string xmlNamespace, string xmlPrefix, int index)
        {
            RegisterNamespace(source, NamespacePrefix, Namespace);

            // Namespace and node provide context, however the prefix if present overrides the node's actual namespace
            source.Push(nodeName, Namespace, xmlPrefix, index);
            try
            {
                if (!source.CurrentNode())
                {
                    return(null);
                }

                var xmlType = string.Empty;
                RegisterNamespace(source, XsiPrefix, XsiNamespace);
                xmlType = source.ToString("type", XsiPrefix, isAttribute: true);

                TDestination destination;

                // This mapper can handle it if there's no type specified or it's our type or if it is the base mapper for an unknown type
                if (string.IsNullOrEmpty(xmlType) || string.IsNullOrEmpty(XmlType))
                {
                    destination = CreateAndMap(source);
                }
                else
                {
                    var t = XmlTypeInfo(source, xmlType);
                    if (t.Item1 == XmlTypeNamespace && t.Item2 == XmlType)
                    {
                        // We're responsible
                        destination = CreateAndMap(source);
                    }
                    else
                    {
                        // Need a mapper for this xsi:type
                        try
                        {
                            destination = XsiMapper(source, nodeName, t.Item1, t.Item2, index);
                        }
                        catch (XmlTypeMappingException)
                        {
                            // if we don't get one try with this base one
                            destination = this.CreateAndMap(source);
                        }
                    }
                }

                return(destination);
            }
            finally
            {
                // Make sure we unwind the stack in all cases
                source.Pop();
            }
        }