Как извлечь значение встроенного атрибута из предыдущего значения атрибута в запросе XPath?
Я пытаюсь "выбрать" ссылку из атрибута onclick в следующей части HTML
<span onclick="Javascript:document.quickFindForm.action='/blah_blah'"
class="specialLinkType"><img src="blah"></span>
но не могу получить дальше, чем следующий XPath
//span[@class="specialLinkType"]/@onclick
который только возвращает
Javascript:document.quickFindForm.action
Любые идеи о том, как выбрать эту ссылку внутри quickFindForm.action
с XPath?
3 ответа
Я пробовал XPath в приложении Java, и он работал нормально:
import java.io.IOException;
import java.io.StringReader;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathFactory;
import org.w3c.dom.Document;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
public class Teste {
public static void main(String[] args) throws Exception {
Document doc = stringToDom("<span onclick=\"Javascript:document.quickFindForm.action='/blah_blah'\" class=\"specialLinkType\"><img src=\"blah\"/></span>");
XPath newXPath = XPathFactory.newInstance().newXPath();
XPathExpression xpathExpr = newXPath.compile("//span[@class=\"specialLinkType\"]/@onclick");
String result = xpathExpr.evaluate(doc);
System.out.println(result);
}
public static Document stringToDom(String xmlSource) throws SAXException, ParserConfigurationException, IOException {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
return builder.parse(new InputSource(new StringReader(xmlSource)));
}
}
Результат:
Javascript:document.quickFindForm.action='/blah_blah'
Если Scrapy поддерживает строковые функции XPath, это будет работать
substring-before(
substring-after(
//span[@class="specialLinkType"]/@onclick,"quickFindForm.action='")
,"'")
Похоже, он также поддерживает регулярные выражения. Как то так должно работать
.select('//span[@class="specialLinkType"]/@onclick').re(r'quickFindForm.action=\'(.*?)\'')
Предостережение: я не могу проверить второе решение, и вам придется проверить это \'
является правильной escape-последовательностью для одинарных кавычек в этом случае.
Я использовал xquery, но он должен быть таким же в xpath. Я использовал функцию xpath "tokenize", которая разбивает строку на основе регулярного выражения (http://www.xqueryfunctions.com/xq/fn_tokenize.html). В этом случае я разбил строку на основе ""
xquery version "1.0";
let $x := //span[@class="specialLinkType"]/@onclick
let $c := fn:tokenize( $x, '''' )
return $c[2]
Что в xpath должно быть:
fn:tokenize(//span[@class="specialLinkType"]/@onclick, '''' )[2]