Xpath के साथ एक css क्लास का चयन करना


87

मैं अपने नाम पर सिर्फ एक वर्ग का चयन करना चाहता हूं

किसी कारण से, मुझे यह काम करने के लिए नहीं मिल सकता है। अगर किसी को पता है कि मेरे कोड में क्या गलत है, तो यह बहुत सराहा जाएगा।

@$doc = new DOMDocument();
@$doc->loadHTML($html);
$xml = simplexml_import_dom($doc); // just to make xpath more simple
$images = $xml->xpath('//[@class="date"]');                             
foreach ($images as $img)
{
    echo  $img." ";
}

2
और html के टुकड़े के बारे में क्या? (AsXML से हमें simpleXml उत्पादन दिखाने के लिए पसंद करें () क्योंकि यह xpath के करीब है)
सर्ज 19

अगर वहाँ कई वर्गों के लिए आप की जरूरत हैcontains(@class, 'date')
गॉर्डन



@ गॉर्डन का जवाब खतरनाक है, अगर क्लास की विशेषता "डेटाइम" है तो यह मेल भी खाएगा। user716736 का जवाब अधिक पूर्ण है।
नील्स बॉम्ब

जवाबों:


242

मैं इस प्रश्न का विहित उत्तर लिखना चाहता हूं क्योंकि उपरोक्त उत्तर में समस्या है।

हमारी समस्या

सीएसएस चयनकर्ता:

.foo

ऐसे किसी भी तत्व का चयन करेगा जिसमें वर्ग foo है

आप XPath में यह कैसे करते हैं?

हालाँकि XPath CSS से अधिक शक्तिशाली है, लेकिन XPath में CSS क्लास चयनकर्ता के मूल समकक्ष नहीं है । हालांकि, एक समाधान है।

इसे करने का सही तरीका

में समतुल्य चयनकर्ता XPath है:

//*[contains(concat(" ", normalize-space(@class), " "), " foo ")]

फ़ंक्शन सामान्य-स्पेस स्ट्रिप्स को लीड करता है और व्हाट्सएप को पीछे छोड़ता है (और एक सिंगल स्पेस द्वारा व्हाट्सएप कैरेक्टर के सीक्वेंस को भी बदल देता है)।

(अधिक सामान्य अर्थ में) यह सीएसएस चयनकर्ता के समकक्ष भी है:

*[class~="foo"]

जो किसी भी तत्व जिसका वर्ग से मेल खाएगा गुण मान व्हाट्सएप-अलग-अलग मूल्यों की एक सूची है, जिनमें से एक फू के बराबर है ।

यह करने के लिए स्पष्ट, लेकिन गलत तरीके के एक जोड़े

XPath चयनकर्ता:

//*[@class="foo"]

काम नहीं करता है! क्योंकि यह एक ऐसे तत्व से मेल नहीं खाएगा जिसमें एक से अधिक वर्ग हों, उदाहरण के लिए

<div class="foo bar">

वर्ग के नाम के आसपास कोई अतिरिक्त व्हाट्सएप होने पर भी यह मेल नहीं खाएगा:

<div class="  foo ">

'बेहतर' XPath चयनकर्ता

//*[contains(@class, "foo")]

या तो काम नहीं करता है! क्योंकि यह गलत तरीके से क्लास फोब्बर के तत्वों से मेल खाता है , उदाहरण के लिए

<div class="foobar">

क्रेडिट इस फेला को जाता है, जो इस समस्या का सबसे पहला प्रकाशित समाधान था जो मुझे वेब पर मिला: http://dubinko.info/blog/2007/10/01/simple-parsing-of-space-seprated-attades- इन-xpathxslt /


सामान्य-स्थान की क्या आवश्यकता है?
फ़्रीक

"ऊपर दिया गया उत्तर" संभवतः मिग्लस को संदर्भित करता है।
लार्स

क्या यह संभव है <div class="foo\tbar">? मेरा मतलब है, एक टैब द्वारा अलग किए गए वर्ग नाम।
जमे हुए लौ

1
लेकिन <div class = "group-conditions" /> और <div class = "condition" /> $ x ('// div] समाहित है (concat (""), normalize-space (@class), " ")," स्थिति ")] ')
मेम्के

1
@ testerjoe2 क्या आपने कोशिश की //*[contains(concat(" ", normalize-space(@class), " "), " foo ")]?
नील्स बॉम

11

//[@class="date"] एक वैध xpath नहीं है।

कोशिश करो //*[@class="date"], या यदि आप जानते हैं कि यह एक छवि है,//img[@class="date"]


7

XPath 3.1 एक फ़ंक्शन को शामिल करता है जिसमें टोकन होता है और इस प्रकार यह अंततः 'आधिकारिक रूप से' हल करता है। इसे वर्गों का समर्थन करने के लिए डिज़ाइन किया गया है ।

उदाहरण:

//*[contains-token(@class, "foo")]

यह फ़ंक्शन सुनिश्चित करता है कि सफेद स्थान (न केवल (U + 0020)) को सही तरीके से संभाला जाता है, वर्ग नाम पुनरावृत्ति के मामले में काम करता है, और आमतौर पर किनारे के मामलों को कवर करता है।


नोट: आज (2016-12-13) के अनुसार XPath 3.1 को कैंडिडेट की अनुशंसा का दर्जा प्राप्त है ।


यह आज के नवीनतम क्रोम में काम नहीं करता है। जब तक यह काम नहीं करता है, हम सीमा के आसपास कैसे पहुंचते हैं कि // * [(@class, "foo")] भी किसी भी वर्ग का चयन करेगा जिसमें फू शामिल है, जैसे कि फ़ॉबर, फ़ूज़ आदि
MasterJoe

3

XPath 2.0 में आप कर सकते हैं:

//*[count(index-of(tokenize(@class, '\s+' ), 'foo')) = 1]

जैसा कि क्रिश्चियन वीसेके ने कहा: https://cweiske.de/tagebuch/XPath%3A%20Select%20element%20by%20class.htm


दुर्भाग्य से यह क्रोम द्वारा 6/12/2017 तक लागू नहीं किया गया है। en.wikipedia.org/wiki/… पर आधारित यह बोर्ड भर में बहुत ज्यादा कमी लगती है
जॉनी राया

1

HTML केस-असंवेदनशील तत्व और विशेषता नामों की अनुमति देता है और फिर वर्ग एक अलग-अलग वर्ग-नामों की सूची है। यहाँ हम एक imgटैग और classनाम के लिए जाते हैं date:

//*['IMG' = translate(name(.), 'abcdefghijklmnopqrstuvwxyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')]/@*['CLASS' = translate(name(.), 'abcdefghijklmnopqrstuvwxyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ') and contains(concat(' ', normalize-space(.), ' '), concat(' ', 'date', ' '))]

साथ ही देखें: CSS सेलेक्टर से XPath रूपांतरण


1

मंदिर में होने वाले मंत्रों का विवरण !!! यदि आप DOM में "my-ownclass" के लिए क्वेरी कर रहे हैं:

<ul class="my-ownclass"><li>...</li></ul>
<ul class="someother"><li>...</li></ul>
<ul><li>...</li></ul>

$finder = new DomXPath($dom);
$nodes = $finder->query(".//ul[contains(@class, 'my-ownclass')]"); // This will NOT behave as expected! This will strangely match all the <ul> elements in DOM.
$nodes = $finder->query(".//ul[contains(@class, 'ownclass')]"); // This will match the element.
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.