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