Quero uma função de correspondência de expressões regulares, mas não existe tal função no XPath 1.0.
Não tive escolha a não ser expandir um sozinho e, depois de pesquisar na Internet, encontrei um bom artigo.
http://www.microsoft.com/china/MSDN/library/data/xml/AddingCustomFunctionstoXpath.mspx?mfr=true
Este artigo define uma divisão e uma substituição, mas não há correspondência.
Tive que expandi-lo com base nele. Depois de
observar cuidadosamente o código, descobri que é muito simples estender uma função, basta modificar estes parágrafos:
1: CustomContext.cs.
// Função para resolver referências às minhas funções personalizadas.
substituição pública IXsltContextFunction ResolveFunction (prefixo de string,
nome da string, XPathResultType[] ArgTypes)
{
XPathRegExtensionFunction func=nulo;
// Cria uma instância da classe de função de extensão apropriada.
mudar (nome)
{
caso "Correspondência":
//Uso
// myFunctions:Matches(string source, string Regex_pattern) retorna Boolean
func = new XPathRegExtensionFunction("Correspondência", 2, 2, novo
XPathResultType[] {XPathResultType.String, XPathResultType.String}
, XPathResultType.Boolean );
quebrar;
caso "Dividir":
//Uso
// myFunctions:Split(string source, string Regex_pattern, int n) retorna string
func = new XPathRegExtensionFunction("Dividir", 3, 3, novo
XPathResultType[] {XPathResultType.String, XPathResultType.String,
XPathResultType.Number}, XPathResultType.String);
quebrar;
caso "Substituir":
//Uso
// myFunctions:Replace(string source, string Regex_pattern, string replacement_string) retorna string
func = new XPathRegExtensionFunction("Substituir", 3, 3, novo
XPathResultType[] {XPathResultType.String, XPathResultType.String,
XPathResultType.String}, XPathResultType.String);
quebrar;
}
função de retorno;
}
2: XPathRegExtensionFunction.cs
// Este método é invocado em tempo de execução para executar a função definida pelo usuário.
objeto público Invoke(XsltContext xsltContext, object[] args,
XPathNavigator docContext)
{
Regex r;
stringstr = nulo;
// As duas funções de extensão XPath personalizadas
switch(m_FunctionName)
{
caso "Correspondência":
r = novo Regex(args[1].ToString());
MatchCollection m = r.Matches(args[0].ToString());
se (m.Contagem == 0)
{
retornar falso;
}
outro
{
retornar verdadeiro;
}
quebrar;
caso "Dividir":
r = novo Regex(args[1].ToString());
string[] s1 = r.Split(args[0].ToString());
int n = Convert.ToInt32(args[2]);
se (s1.Comprimento <n)
str = "";
outro
str = s1[n - 1];
quebrar;
caso "Substituir":
r = novo Regex(args[1].ToString());
string s2 = r.Replace(args[0].ToString(), args[2].ToString());
str = s2;
quebrar;
}
retornar (objeto)str;
}
Outro arquivo, XPathExtensionVariable.cs, na verdade não tem nada a ver com expansão de função. Ele é usado para definir parâmetros.
Depois que esses dois arquivos forem modificados, você poderá chamar:
consulta = navigator.Compile("xdUtil:Match(9,'\d')");
CustomContext cntxt = new CustomContext();
// Adicione uma definição de namespace para o prefixo myFunctions.
cntxt.AddNamespace("xdUtil", " http://myXPathExtensionFunctions ");
consulta.SetContext(cntxt);
Avaliar(consulta, navegador);
Claro, seria ótimo se ele suportasse XPath2.0. Todas essas funções do XPath2.0 são suportadas internamente, mas infelizmente ainda não parece ser compatível.
O código completo está aqui: