diff options
Diffstat (limited to 'Xamarin.Forms.Xaml/XamlParser.cs')
-rw-r--r-- | Xamarin.Forms.Xaml/XamlParser.cs | 77 |
1 files changed, 45 insertions, 32 deletions
diff --git a/Xamarin.Forms.Xaml/XamlParser.cs b/Xamarin.Forms.Xaml/XamlParser.cs index 7dd79d77..60424754 100644 --- a/Xamarin.Forms.Xaml/XamlParser.cs +++ b/Xamarin.Forms.Xaml/XamlParser.cs @@ -38,7 +38,10 @@ namespace Xamarin.Forms.Xaml { public static void ParseXaml(RootNode rootNode, XmlReader reader) { - var attributes = ParseXamlAttributes(reader); + IList<KeyValuePair<string, string>> xmlns; + var attributes = ParseXamlAttributes(reader, out xmlns); + var prefixes = PrefixesToIgnore(xmlns); + (rootNode.IgnorablePrefixes ?? (rootNode.IgnorablePrefixes=new List<string>())).AddRange(prefixes); rootNode.Properties.AddRange(attributes); ParseXamlElementFor(rootNode, reader); } @@ -136,8 +139,10 @@ namespace Xamarin.Forms.Xaml var elementName = reader.Name; var elementNsUri = reader.NamespaceURI; var elementXmlInfo = (IXmlLineInfo)reader; + IList<KeyValuePair<string, string>> xmlns; - var attributes = ParseXamlAttributes(reader); + var attributes = ParseXamlAttributes(reader, out xmlns); + var prefixes = PrefixesToIgnore(xmlns); IList<XmlType> typeArguments = null; if (attributes.Any(kvp => kvp.Key == XmlName.xTypeArguments)) @@ -149,6 +154,7 @@ namespace Xamarin.Forms.Xaml node = new ElementNode(new XmlType(elementNsUri, elementName, typeArguments), elementNsUri, reader as IXmlNamespaceResolver, elementXmlInfo.LineNumber, elementXmlInfo.LinePosition); ((IElementNode)node).Properties.AddRange(attributes); + (node.IgnorablePrefixes ?? (node.IgnorablePrefixes = new List<string>())).AddRange(prefixes); ParseXamlElementFor((IElementNode)node, reader); nodes.Add(node); @@ -170,17 +176,20 @@ namespace Xamarin.Forms.Xaml throw new XamlParseException("Closing PropertyElement expected", (IXmlLineInfo)reader); } - static IList<KeyValuePair<XmlName, INode>> ParseXamlAttributes(XmlReader reader) + static IList<KeyValuePair<XmlName, INode>> ParseXamlAttributes(XmlReader reader, out IList<KeyValuePair<string,string>> xmlns) { Debug.Assert(reader.NodeType == XmlNodeType.Element); var attributes = new List<KeyValuePair<XmlName, INode>>(); + xmlns = new List<KeyValuePair<string, string>>(); for (var i = 0; i < reader.AttributeCount; i++) { reader.MoveToAttribute(i); //skip xmlns - if (reader.NamespaceURI == "http://www.w3.org/2000/xmlns/") + if (reader.NamespaceURI == "http://www.w3.org/2000/xmlns/") { + xmlns.Add(new KeyValuePair<string, string>(reader.LocalName, reader.Value)); continue; + } var propertyName = new XmlName(reader.NamespaceURI, reader.LocalName); @@ -239,6 +248,23 @@ namespace Xamarin.Forms.Xaml return attributes; } + static IList<string> PrefixesToIgnore(IList<KeyValuePair<string, string>> xmlns) + { + var prefixes = new List<string>(); + foreach (var kvp in xmlns) { + var prefix = kvp.Key; + + string typeName = null, ns = null, asm = null, targetPlatform = null; + XmlnsHelper.ParseXmlns(kvp.Value, out typeName, out ns, out asm, out targetPlatform); + if (targetPlatform == null) + continue; + TargetPlatform os; + if (Enum.TryParse<TargetPlatform>(targetPlatform, out os) && os != Device.OS) + prefixes.Add(prefix); + } + return prefixes; + } + static IValueNode GetValueNode(object value, XmlReader reader) { var valueString = value as string; @@ -264,31 +290,26 @@ namespace Xamarin.Forms.Xaml var typeArguments = xmlType.TypeArguments; exception = null; - List<Tuple<string, Assembly>> lookupAssemblies = new List<Tuple<string, Assembly>>(); - List<string> lookupNames = new List<string>(); + var lookupAssemblies = new List<Tuple<string, string>>(); //namespace, assemblyqualifiednamed + var lookupNames = new List<string>(); if (!XmlnsHelper.IsCustom(namespaceURI)) { - lookupAssemblies.Add(new Tuple<string, Assembly>("Xamarin.Forms", typeof (View).GetTypeInfo().Assembly)); - lookupAssemblies.Add(new Tuple<string, Assembly>("Xamarin.Forms.Xaml", typeof (XamlLoader).GetTypeInfo().Assembly)); + lookupAssemblies.Add(new Tuple<string, string>("Xamarin.Forms", typeof (View).GetTypeInfo().Assembly.FullName)); + lookupAssemblies.Add(new Tuple<string, string>("Xamarin.Forms.Xaml", typeof (XamlLoader).GetTypeInfo().Assembly.FullName)); } else if (namespaceURI == "http://schemas.microsoft.com/winfx/2009/xaml" || namespaceURI == "http://schemas.microsoft.com/winfx/2006/xaml") { - lookupAssemblies.Add(new Tuple<string, Assembly>("Xamarin.Forms.Xaml", typeof (XamlLoader).GetTypeInfo().Assembly)); - lookupAssemblies.Add(new Tuple<string, Assembly>("System", typeof (object).GetTypeInfo().Assembly)); - lookupAssemblies.Add(new Tuple<string, Assembly>("System", typeof (Uri).GetTypeInfo().Assembly)); //System.dll + lookupAssemblies.Add(new Tuple<string, string>("Xamarin.Forms.Xaml", typeof (XamlLoader).GetTypeInfo().Assembly.FullName)); + lookupAssemblies.Add(new Tuple<string, string>("System", typeof (object).GetTypeInfo().Assembly.FullName)); //mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + lookupAssemblies.Add(new Tuple<string, string>("System", typeof (Uri).GetTypeInfo().Assembly.FullName)); //System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 } else { - string ns; - string typename; - string asmstring; - Assembly asm; - - XmlnsHelper.ParseXmlns(namespaceURI, out typename, out ns, out asmstring); - asm = asmstring == null ? currentAssembly : Assembly.Load(new AssemblyName(asmstring)); - lookupAssemblies.Add(new Tuple<string, Assembly>(ns, asm)); + string ns, asmstring, _; + XmlnsHelper.ParseXmlns(namespaceURI, out _, out ns, out asmstring, out _); + lookupAssemblies.Add(new Tuple<string, string>(ns, asmstring ?? currentAssembly.FullName)); } lookupNames.Add(elementName); @@ -305,16 +326,12 @@ namespace Xamarin.Forms.Xaml } Type type = null; - foreach (var asm in lookupAssemblies) - { - if (type != null) - break; + foreach (var asm in lookupAssemblies) { foreach (var name in lookupNames) - { - if (type != null) + if ((type = Type.GetType($"{asm.Item1}.{name}, {asm.Item2}")) != null) break; - type = asm.Item2.GetType(asm.Item1 + "." + name); - } + if (type != null) + break; } if (type != null && typeArguments != null) @@ -340,11 +357,7 @@ namespace Xamarin.Forms.Xaml } if (type == null) - { - exception = new XamlParseException(string.Format("Type {0} not found in xmlns {1}", elementName, namespaceURI), - xmlInfo); - return null; - } + exception = new XamlParseException($"Type {elementName} not found in xmlns {namespaceURI}", xmlInfo); return type; } |