如果需要更全面的解决方案,您可以为XPath处理器编写一个扩展函数,该函数将执行不区分大小写的比较。虽然代码量很大,但您只需编写一次即可。
实现扩展函数后,您可以按以下方式编写查询:
"//meta[@name[Extensions:CaseInsensitiveComparison('Keywords')]]"
下面是示例中实现的扩展函数Extensions:CaseInsensitiveComparison
。
注意:这并没有经过充分测试,我只是为了回答这个问题而匆忙编写,因此错误处理等都不存在!
以下是自定义XSLT上下文的代码,提供一个或多个扩展函数。
using System;
using System.Xml.XPath;
using System.Xml.Xsl;
using System.Xml;
using HtmlAgilityPack;
public class XsltCustomContext : XsltContext
{
public const string NamespaceUri = "http://XsltCustomContext";
public XsltCustomContext()
{
}
public XsltCustomContext(NameTable nt)
: base(nt)
{
}
public override IXsltContextFunction ResolveFunction(string prefix, string name, XPathResultType[] ArgTypes)
{
if (this.LookupNamespace(prefix) == NamespaceUri)
{
switch (name)
{
case "CaseInsensitiveComparison":
return CaseInsensitiveComparison.Instance;
}
}
return null;
}
public override IXsltContextVariable ResolveVariable(string prefix, string name)
{
return null;
}
public override int CompareDocument(string baseUri, string nextbaseUri)
{
return 0;
}
public override bool PreserveWhitespace(XPathNavigator node)
{
return false;
}
public override bool Whitespace
{
get { return true; }
}
class CaseInsensitiveComparison : IXsltContextFunction
{
private static XPathResultType[] _argTypes = new XPathResultType[] { XPathResultType.String };
private static CaseInsensitiveComparison _instance = new CaseInsensitiveComparison();
public static CaseInsensitiveComparison Instance
{
get { return _instance; }
}
#region IXsltContextFunction Members
public XPathResultType[] ArgTypes
{
get { return _argTypes; }
}
public int Maxargs
{
get { return 1; }
}
public int Minargs
{
get { return 1; }
}
public XPathResultType ReturnType
{
get { return XPathResultType.Boolean; }
}
public object Invoke(XsltContext xsltContext, object[] args, XPathNavigator navigator)
{
string text = args[0] as string;
return string.Equals(navigator.Value, text, StringComparison.InvariantCultureIgnoreCase);
}
#endregion
}
}
您可以在XPath查询中使用上述扩展函数,这里是我们案例的示例。
class Program
{
static string html = "<html><meta name=\"keywords\" content=\"HTML, CSS, XML\" /></html>";
static void Main(string[] args)
{
HtmlDocument doc = new HtmlDocument();
doc.LoadHtml(html);
XPathNavigator nav = doc.CreateNavigator();
XsltCustomContext ctx = new XsltCustomContext(new NameTable());
ctx.AddNamespace("Extensions", XsltCustomContext.NamespaceUri);
XPathExpression xpath =
XPathExpression.Compile("//meta[@name[Extensions:CaseInsensitiveComparison('Keywords')]]");
xpath.SetContext(ctx);
var element = nav.SelectSingleNode(xpath);
}
}