केस असंवेदनशील XPath में () संभव है?


93

मैं अपने DOM के सभी टेक्स्ट पर चल रहा हूं और जांचता हूं कि नोडवैल्यू में एक निश्चित स्ट्रिंग है या नहीं।

/html/body//text()[contains(.,'test')]

यह मामला संवेदनशील है। हालांकि, मैं भी पकड़ना चाहता हूं Test, TESTया TesT। क्या XPath (जावास्क्रिप्ट में) के साथ संभव है?

जवाबों:


110

यह XPath 1.0 के लिए है। यदि आपका वातावरण XPath 2.0 का समर्थन करता है, तो यहां देखें ।


हाँ। संभव है, लेकिन सुंदर नहीं।

/html/body//text()[
  contains(
    translate(., 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'),
    'test'
  )
]

यह उन खोज तारों के लिए काम करेगा जहाँ वर्णमाला पहले से जानी जाती है। आपके द्वारा देखे जाने वाले किसी भी उच्चारण वर्ण को जोड़ें।


यदि आप कर सकते हैं, तो उस पाठ को चिह्नित करें जो आपको किसी अन्य माध्यम से रुचिकर बनाता है, जैसे <span>कि HTML बनाने के दौरान इसमें एक निश्चित वर्ग होता है। इस तरह की चीजों को तत्व पाठ में सब्सट्रिंग्स की तुलना में एक्सपीथ के साथ पता लगाना बहुत आसान है।

यदि यह विकल्प नहीं है, तो आप जावास्क्रिप्ट (या किसी अन्य होस्ट भाषा का उपयोग कर सकते हैं जिसे आप XPath निष्पादित करने के लिए उपयोग कर रहे हैं) आपको एक गतिशील XPath अभिव्यक्ति बनाने में मदद कर सकती है:

function xpathPrepare(xpath, searchString) {
  return xpath.replace("$u", searchString.toUpperCase())
              .replace("$l", searchString.toLowerCase())
              .replace("$s", searchString.toLowerCase());
}

xp = xpathPrepare("//text()[contains(translate(., '$u', '$l'), '$s')]", "Test");
// -> "//text()[contains(translate(., 'TEST', 'test'), 'test')]"

(Hat टिप @ KirillPolenchuk के उत्तर के लिए - निश्चित रूप से आपको केवल उन पात्रों का अनुवाद करना होगा जिन्हें आप वास्तव में खोज रहे हैं )।

यह दृष्टिकोण वर्णमाला के पूर्व ज्ञान की आवश्यकता के बिना किसी भी खोज स्ट्रिंग के लिए काम करेगा, जो कि एक बड़ा प्लस है।

ऊपर दिए गए दोनों तरीके विफल हो जाते हैं जब खोज के तार एकल उद्धरण शामिल हो सकते हैं, जिस स्थिति में चीजें अधिक जटिल हो जाती हैं


धन्यवाद! इसके अलावा इसके अलावा अच्छा है, केवल आवश्यक वर्णों का अनुवाद। मुझे उत्सुकता होगी कि प्रदर्शन जीत क्या है। ध्यान दें कि xpathPrepare () एक से अधिक बार प्रदर्शित होने वाले चार्ट को अलग-अलग तरीके से संभाल सकता है (जैसे कि आपको टीईईईईईईएसईएस और टीइएस्ट)।
एरन वोस्त

@ एरोनवोस्ट: ठीक है, कुछ लाभ हो सकता है, अगर आप यह पता लगाने के लिए उत्सुक हैं तो इसे बेंचमार्क करें। translate()अपने आप को परवाह नहीं है कि आप कितनी बार प्रत्येक चरित्र को दोहराते हैं - translate(., 'EE', 'ee')बिल्कुल बराबर है translate(., 'E', 'e')पुनश्च: @KirillPolenchuk को मत देना, विचार था उसका।
टॉमालक

2
System.Xml.XmlNodeList x = mydoc.SelectNodes ("// * [होता है (अनुवाद (पाठ)), 'ABCDEFGHIJKLMNOPQRSTUVWXYZÄÖÜÉÈÊÀÁÂÒÓÔÙÚÛÇÅÏÕÑŒ', 'abcdefghijklmnopqrstrstvwxyzäövécôtácócátócócócátá।"
स्टीफन स्टीगर

1
नहीं, "निश्चित रूप से आपको केवल उन पात्रों का अनुवाद करने की आवश्यकता है जिन्हें आप वास्तव में खोज रहे हैं" भाग।
तोमलक

60

अधिक सुंदर:

/html/body//text()[contains(translate(., 'TES', 'tes'), 'test')]

4
+1 बिल्कुल। ऐसा कुछ जो मैंने नहीं सोचा था। (मैं अपने जवाब में इसका उपयोग करूँगा, यह मेरे द्वारा लिखे गए मूल जावास्क्रिप्ट दिनचर्या से बहुत बेहतर है)
टॉमालक

4
यह सिर्फ रूपांतरित नहीं होता TESTहै testऔर Testजैसा है वैसा ही रह जाता है?
मुहम्मद अदील जाहिद

6
@MuhammadAdeelZahid - नहीं, यह "टी" के साथ "टी", "ई" के साथ "ई", आदि की जगह ले रहा है। यह 1 से 1 का मैच है।
डैनियल हैली

यह करने के लिए अधिक स्पष्ट हो सकता है translate(., 'TES', 'tes')। इस तरह से लोगों को एहसास होगा कि यह एक शब्द अनुवाद नहीं है, कि यह एक पत्र अनुवाद है।
23

54

XPath 2.0 समाधान

  1. लो-केस () का प्रयोग करें :

    /html/body//text()[contains(lower-case(.),'test')]

  2. मैचों का उपयोग करें () अपने केस-असंवेदनशील झंडे के साथ रेगेक्स मिलान:

    /html/body//text()[matches(.,'test', 'i')]


1
क्या यह सिंटैक्स फ़ायरफ़ॉक्स और क्रोम में समर्थित नहीं है? मैंने इसे कंसोल में आज़माया और वे दोनों सिंटैक्स त्रुटि लौटाते हैं।
db

1
फ़ायरफ़ॉक्स और क्रोम केवल XPath 1.0 को लागू करते हैं।
kjhughes

8

हाँ। आप translateनिम्न के रूप में निम्न मामले से मेल खाने वाले पाठ को परिवर्तित करने के लिए उपयोग कर सकते हैं :

/html/body//text()[contains(translate(., 
                                      'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
                                      'abcdefghijklmnopqrstuvwxyz'),
                   'test')]

6

यदि आप XPath 2.0 का उपयोग कर रहे हैं, तो आप किसी कॉलेशन को तीसरे तर्क के रूप में निर्दिष्ट कर सकते हैं ()। हालाँकि, कोलाज यूआरआई को मानकीकृत नहीं किया जाता है, इसलिए विवरण उस उत्पाद पर निर्भर करता है जिसका आप उपयोग कर रहे हैं।

ध्यान दें कि अनुवाद () का उपयोग करके पहले दिए गए समाधान सभी मानते हैं कि आप केवल 26-अक्षर वाले अंग्रेजी वर्णमाला का उपयोग कर रहे हैं।

अद्यतन: XPath 3.1 केस-अंधी मिलान के लिए एक मानक टकराव URI को परिभाषित करता है।


3

XPath में "ट्रांसलेट" फ़ंक्शन का उपयोग करके मैंने हमेशा ऐसा किया। मैं इसके बहुत सुंदर नहीं कहूँगा, लेकिन यह सही ढंग से काम करता है।

/html/body//text()[contains(translate(.,'abcdefghijklmnopqrstuvwxyz',
                                        'ABCDEFGHIJKLOMNOPQRSTUVWXYZ'),'TEST')]

उम्मीद है की यह मदद करेगा,

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.