public override object BeforeMethod(string method) { // Raw Xpath // {{ data.xpath['/name/first/@type'] }} if (method == xpathQueryMethodName) { return(new XPathQuery(doc)); } // A list of nodes // {{ for person in data.list['//person'] }} if (method == listQueryMethodName) { return(new ListQuery(doc)); } // List shortcut // {% for person in data.list-person %} // Prepends "//", so it's the same as the prior example if (StartsWithMethodName(method, listQueryMethodName)) { return(ListQuery.GetDrops(doc, string.Concat(".//", GetShorthandValue(method)))); } // Attribute shortcut // {{ data.name.first.attr-type }} // Same as the XPath example above if (StartsWithMethodName(method, attributeMethodName)) { return(doc.Attributes[GetShorthandValue(method)]?.Value); } // We have nothing for this node, return an empty string if (doc.SelectSingleNode(GetPathToNode(method)) == null) { return(string.Empty); } // We have inner text for this node, then this is what they actually want, so return it if (doc.SelectSingleNode(GetPathToTextNode(method)) != null) { return(doc.SelectSingleNode(GetPathToTextNode(method)).InnerText); } // If there's no text, then assume they want to drill down into the inner XML of it return(new XmlNode((XmlElement)doc.SelectSingleNode(GetPathToNode(method)))); }