ฉันต้องการฟังก์ชันจับคู่นิพจน์ทั่วไป แต่ไม่มีฟังก์ชันดังกล่าวใน XPath 1.0
ฉันไม่มีทางเลือกนอกจากต้องขยายตัวเองและหลังจากค้นหาบนอินเทอร์เน็ตก็มีบทความดีๆ
http://www.microsoft.com/china/MSDN/library/data/xml/AddingCustomFunctionstoXpath.mspx?mfr=true
บทความนี้กำหนดการแยกและการแทนที่ แต่ไม่มีรายการที่ตรงกัน
ฉันต้องขยายมันบนพื้นฐานของมัน หลังจาก
สังเกตโค้ดอย่างระมัดระวัง ฉันพบว่าการขยายฟังก์ชันนั้นง่ายมาก เพียงแก้ไขย่อหน้าเหล่านี้:
1: CustomContext.cs
// ฟังก์ชันสำหรับแก้ไขการอ้างอิงถึงฟังก์ชันที่กำหนดเองของฉัน
การแทนที่สาธารณะ IXsltContextFunction ResolveFunction (คำนำหน้าสตริง
ชื่อสตริง XPathResultType[] ArgTypes)
-
XPathRegExtensionFunction func = null;
// สร้างอินสแตนซ์ของคลาสฟังก์ชันส่วนขยายที่เหมาะสม
สวิตช์ (ชื่อ)
-
กรณี "ตรงกัน":
//การใช้งาน
// myFunctions:Matches(string source, string Regex_pattern) ส่งคืนบูลีน
func = new XPathRegExtensionFunction("Match", 2, 2, new
XPathResultType[] {XPathResultType.String, XPathResultType.String}
, XPathResultType.บูลีน );
หยุดพัก;
กรณี "แยก":
//การใช้งาน
// myFunctions:Split(string source, string Regex_pattern, int n) ส่งคืนสตริง
func = new XPathRegExtensionFunction("แยก", 3, 3, ใหม่
XPathResultType[] {XPathResultType.String, XPathResultType.String,
XPathResultType.Number}, XPathResultType.String);
หยุดพัก;
กรณี "แทนที่":
//การใช้งาน
// myFunctions:Replace(แหล่งสตริง, สตริง Regex_pattern, สตริง replacement_string) ส่งคืนสตริง
func = new XPathRegExtensionFunction("แทนที่", 3, 3, new
XPathResultType[] {XPathResultType.String, XPathResultType.String,
XPathResultType.String}, XPathResultType.String);
หยุดพัก;
-
ฟังก์ชั่นส่งคืน;
-
2: XPathRegExtensionFunction.cs
// วิธีการนี้ถูกเรียกใช้ ณ รันไทม์เพื่อดำเนินการฟังก์ชันที่ผู้ใช้กำหนด
วัตถุสาธารณะวิงวอน (XsltContext xsltContext, object [] args,
XPathNavigator docContext)
-
Regex r;
สตริง str = null;
// ฟังก์ชันส่วนขยาย XPath ที่กำหนดเองสองฟังก์ชัน
สวิตช์ (m_FunctionName)
-
กรณี "ตรงกัน":
r = Regex ใหม่ (args [1].ToString ());
MatchCollection m = r.Matches(args[0].ToString());
ถ้า (m.Count == 0)
-
กลับเท็จ;
-
อื่น
-
กลับเป็นจริง;
-
แตก;
กรณี "แยก":
r = Regex ใหม่ (args [1].ToString ());
สตริง [] s1 = r.Split (args [0]. ToString ());
int n = Convert.ToInt32(args[2]);
ถ้า (s1.ความยาว < n)
STR = "";
อื่น
STR = s1[n - 1];
หยุดพัก;
กรณี "แทนที่":
r = Regex ใหม่ (args [1].ToString ());
สตริง s2 = r.Replace(args[0].ToString(), args[2].ToString());
STR = s2;
หยุดพัก;
-
กลับ (วัตถุ)str;
-
ไฟล์อื่น XPathExtensionVariable.cs จริงๆ แล้วไม่มีส่วนเกี่ยวข้องกับการขยายฟังก์ชัน มันถูกใช้เพื่อตั้งค่าพารามิเตอร์
หลังจากแก้ไขไฟล์ทั้งสองนี้แล้ว คุณสามารถโทร:
query = navigator.Compile("xdUtil:Match(9,'\d')");
CustomContext cntxt = CustomContext ใหม่ ();
// เพิ่มคำจำกัดความของเนมสเปซสำหรับคำนำหน้า myFunctions
cntxt.AddNamespace("xdUtil", " http://myXPathExtensionFunctions ");
แบบสอบถาม SetContext (cntxt);
ประเมิน (แบบสอบถาม, ตัวนำทาง);
แน่นอนว่าคงจะดีไม่น้อยหากรองรับ XPath2.0 ฟังก์ชั่นเหล่านี้ของ XPath2.0 ได้รับการรองรับในตัวทั้งหมด แต่น่าเสียดายที่ดูเหมือนว่าจะยังไม่รองรับ
รหัสเต็มอยู่ที่นี่: