Quiero una función de coincidencia de expresiones regulares, pero no existe tal función en XPath 1.0.
No tuve más remedio que ampliar uno yo mismo y, después de buscar en Internet, encontré un buen artículo.
http://www.microsoft.com/china/MSDN/library/data/xml/AddingCustomFunctionstoXpath.mspx?mfr=true
Este artículo define una división y un reemplazo, pero no hay coincidencia.
Tuve que expandirlo en base a él. Después de
observar cuidadosamente el código, descubrí que es muy simple extender una función, simplemente modifique estos párrafos:
1: CustomContext.cs.
// Función para resolver referencias a mis funciones personalizadas.
anulación pública IXsltContextFunction ResolveFunction (prefijo de cadena,
nombre de cadena, XPathResultType[] ArgTypes)
{
XPathRegExtensionFunction func = nulo;
// Crea una instancia de la clase de función de extensión adecuada.
cambiar(nombre)
{
caso "Coincidencia":
//Uso
// myFunctions:Matches(fuente de cadena, cadena Regex_pattern) devuelve booleano
func = nueva XPathRegExtensionFunction("Coincidencia", 2, 2, nueva
XPathResultType[] {XPathResultType.String, XPathResultType.String}
, XPathResultType.Booleano);
romper;
caso "Dividir":
//Uso
// misFunciones:Split(fuente de cadena, cadena Regex_pattern, int n) devuelve cadena
func = nueva XPathRegExtensionFunction("Dividir", 3, 3, nueva
XPathResultType[] {XPathResultType.String, XPathResultType.String,
XPathResultType.Number}, XPathResultType.String);
romper;
caso "Reemplazar":
//Uso
// misFunciones:Reemplazar(fuente de cadena, cadena Regex_pattern, cadena cadena_reemplazo) devuelve cadena
func = nueva XPathRegExtensionFunction("Reemplazar", 3, 3, nuevo
XPathResultType[] {XPathResultType.String, XPathResultType.String,
XPathResultType.String}, XPathResultType.String);
romper;
}
función de retorno;
}
2: XPathRegExtensionFunction.cs
// Este método se invoca en tiempo de ejecución para ejecutar la función definida por el usuario.
objeto público Invocar (XsltContext xsltContext, objeto[] args,
XPathNavigator docContext)
{
expresión regular r;
cadena cadena = nulo;
// Las dos funciones de extensión XPath personalizadas
cambiar(m_NombreFunción)
{
caso "Coincidencia":
r = nueva expresión regular (args[1].ToString());
MatchCollection m = r.Matches(args[0].ToString());
si (m.Count == 0)
{
devolver falso;
}
demás
{
devolver verdadero;
}
romper;
caso "Dividir":
r = nueva expresión regular (args[1].ToString());
cadena[] s1 = r.Split(args[0].ToString());
int n = Convert.ToInt32(args[2]);
si (s1.Longitud < n)
cadena = "";
demás
cadena = s1[n - 1];
romper;
caso "Reemplazar":
r = nueva expresión regular (args[1].ToString());
cadena s2 = r.Replace(args[0].ToString(), args[2].ToString());
cadena = s2;
romper;
}
devolver (objeto) str;
}
Otro archivo, XPathExtensionVariable.cs, en realidad no tiene nada que ver con la expansión de funciones. Se utiliza para establecer parámetros.
Una vez modificados estos dos archivos, puede llamar:
consulta = navigator.Compile("xdUtil:Match(9,'\d')");
CustomContext cntxt = nuevo CustomContext();
// Agregue una definición de espacio de nombres para el prefijo myFunctions.
cntxt.AddNamespace("xdUtil", " http://myXPathExtensionFunctions ");
consulta.SetContext(cntxt);
Evaluar(consulta, navegador);
Por supuesto, sería fantástico si fuera compatible con XPath2.0. Todas estas funciones de XPath2.0 son compatibles de forma integrada, pero desafortunadamente no parece serlo todavía.
El código completo está aquí: