/// <summary> /// Called when the user accesses a property dynamically (e.g. "xn.Countries") /// </summary> /// <returns>Depending on the data, this may return a collection of nodes /// or a single node or a string value.</returns> public override bool TryGetMember(GetMemberBinder binder, out object result) { result = null; // First search for nested elements var elems = container.Elements(nameResolver(binder.Name)); if (elems.Count() == 1) { // Single element - wrap it inside DynamicXml result = new DynamicXml(elems.First(), ns, camelCase); } else if (elems.Count() != 0) { // Multiple elements - wrapp all inside DynamicXml & return sequecne result = elems.Select(e => new DynamicXml(e, ns, camelCase)); } else { // No sub-element found. If the current node is Element, try attributes var element = container as XElement; if (element != null) { result = element.Attributes(nameResolver(binder.Name)).FirstOrDefault(); } // Special name 'Value' can be used to get the inner text. if (binder.Name == "Value") { result = element.Value; } } return(result != null); }
/// <summary> /// Called when the user accesses a property dynamically (e.g. "xn.Countries") /// </summary> /// <returns>Depending on the data, this may return a collection of nodes /// or a single node or a string value.</returns> public override bool TryGetMember(GetMemberBinder binder, out object result) { result = null; // First search for nested elements var elems = container.Elements(nameResolver(binder.Name)); if (elems.Count() == 1) // Single element - wrap it inside DynamicXml result = new DynamicXml(elems.First(), ns, camelCase); else if (elems.Count() != 0) { // Multiple elements - wrapp all inside DynamicXml & return sequecne result = elems.Select(e => new DynamicXml(e, ns, camelCase)); } else { // No sub-element found. If the current node is Element, try attributes var element = container as XElement; if (element != null) result = element.Attributes(nameResolver(binder.Name)).FirstOrDefault(); // Special name 'Value' can be used to get the inner text. if (binder.Name == "Value") result = element.Value; } return result != null; }
/// <summary> /// Called when the C# code using 'dynamic' uses "wb.Foo(...)". The method /// treats this as a call to the "foo" service provided by WorldBank. The /// method takes an anonymous type as an argument, so it is possible to /// specify any additional parameters dynamically. /// </summary> /// <example><code> /// dynamic wb = new DynamicWorldBank(); /// dynamic regions = wb.Region(new { PerPage = 100 }); /// </code></example> /// <returns> /// Returns an instance of 'DynamicXml' type that can be used for easy /// access to XML documents using C# 4 'dynamic' keyword. /// </returns> public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result) { // Create URL for the request string url = "http://api.worldbank.org/" + new String(NormalizeName(binder.Name).ToArray()); if (args.Length == 1) { // If there is some anonymous type as argument, get its properties // and append them as arguments to the URL var separator = "?"; foreach (var prop in args[0].GetType().GetProperties()) { url = url + separator + new String(NormalizeName(prop.Name).ToArray()) + "=" + prop.GetValue(args[0], new object[] {}).ToString(); separator = "&"; } } // Perform HTTP request & return result as DynamicXml result = new DynamicXml(url, CamelCase: true, Namespace: "http://www.worldbank.org"); return true; }