Je veux une fonction de correspondance d'expression régulière, mais une telle fonction n'existe pas dans XPath 1.0.
Je n’ai eu d’autre choix que d’en développer un moi-même, et après une recherche sur Internet, j’ai trouvé un bon article.
http://www.microsoft.com/china/MSDN/library/data/xml/AddingCustomFunctionstoXpath.mspx?mfr=true
Cet article définit un fractionnement et un remplacement, mais il n'y a aucune correspondance.
J'ai dû l'étendre sur cette base. Après avoir
soigneusement observé le code, j'ai trouvé qu'il est très simple d'étendre une fonction, il suffit de modifier ces paragraphes :
1 : CustomContext.cs.
// Fonction pour résoudre les références à mes fonctions personnalisées.
remplacement public IXsltContextFunction ResolveFunction(préfixe de chaîne,
nom de chaîne, XPathResultType[] ArgTypes)
{
XPathRegExtensionFunction func = null ;
// Crée une instance de la classe de fonctions d'extension appropriée.
commutateur (nom)
{
cas "Correspondance":
//Usage
// mesFonctions:Matches(string source, string Regex_pattern) renvoie un booléen
func = nouveau XPathRegExtensionFunction("Match", 2, 2, nouveau
XPathResultType[] {XPathResultType.String, XPathResultType.String}
, XPathResultType.Boolean );
casser;
cas "Split":
//Usage
// mesFonctions : Split (source de chaîne, chaîne Regex_pattern, int n) renvoie une chaîne
func = nouveau XPathRegExtensionFunction("Split", 3, 3, nouveau
XPathResultType[] {XPathResultType.String, XPathResultType.String,
XPathResultType.Number}, XPathResultType.String);
casser;
cas "Remplacer":
//Usage
// mesFonctions : Remplacer (source de chaîne, chaîne Regex_pattern, chaîne de remplacement_string) renvoie une chaîne
func = new XPathRegExtensionFunction("Remplacer", 3, 3, nouveau
XPathResultType[] {XPathResultType.String, XPathResultType.String,
XPathResultType.String}, XPathResultType.String);
casser;
}
fonction de retour ;
}
2 : XPathRegExtensionFunction.cs
// Cette méthode est invoquée au moment de l'exécution pour exécuter la fonction définie par l'utilisateur.
objet public Invoke(XsltContext xsltContext, object[] args,
XPathNavigator docContext)
{
Expression régulière r ;
chaîne str = null ;
// Les deux fonctions d'extension XPath personnalisées
commutateur (m_FunctionName)
{
cas "Correspondance":
r = new Regex(args[1].ToString());
MatchCollection m = r.Matches(args[0].ToString());
si (m.Count == 0)
{
renvoie faux ;
}
autre
{
renvoie vrai ;
}
pause ;
cas "Split » :
r = new Regex(args[1].ToString());
string[] s1 = r.Split(args[0].ToString());
int n = Convert.ToInt32(args[2]);
si (s1.Longueur < n)
str = "" ;
autre
str = s1[n - 1];
casser;
cas "Remplacer":
r = new Regex(args[1].ToString());
chaîne s2 = r.Replace(args[0].ToString(), args[2].ToString());
str = s2 ;
casser;
}
return (objet)str;
}
Un autre fichier, XPathExtensionVariable.cs, n'a en réalité rien à voir avec l'expansion des fonctions. Il est utilisé pour définir les paramètres.
Après avoir modifié ces deux fichiers, vous pouvez appeler :
query = navigator.Compile("xdUtil:Match(9,'\d')");
CustomContext cntxt = new CustomContext();
// Ajout d'une définition d'espace de noms pour le préfixe myFunctions.
cntxt.AddNamespace("xdUtil", " http://myXPathExtensionFunctions ");
requête.SetContext(cntxt);
Évaluer(requête, navigateur) ;
Bien sûr, ce serait formidable s'il prend en charge XPath2.0. Ces fonctions de XPath2.0 sont toutes prises en charge de manière intégrée, mais malheureusement, elles ne semblent pas encore prises en charge.
Le code complet est ici :