2011-02-01 2 views
3

Я пытаюсь разобрать веб-страницу, чтобы получать сообщения с форума.
Начало каждого сообщения начинается со следующим форматомПроблема с использованием Xpath «начинается с» для разбора xhtml

<div id="post_message_somenumber"> 

, и я только хочу, чтобы получить первый один

Я попытался xpath='//div[starts-with(@id, '"post_message_')]' в YQL без успеха
Я все еще учусь этому, кто-то есть предложения

+0

Хороший вопрос, +1. См. Мой ответ для двух возможных причин проблемы и решения. –

+2

Проблема связана с кавычками и (возможно, вторично) значением 'id' (он не начинается с двойной кавычки). Вы хотите что-то вроде 'xpath = '// div [start-with (@id," post_message _ ")]'' – salathe

+0

Я не знаю, что такое yql, но я подозреваю, что проблема связана с тем, как вы пишете выражение XPath, содержащее кавычки, а затем вставлять его или скрывать в среде вашего языка. –

ответ

4

Я попытался xpath='//div[starts-with(@id, '"post_message_')]' в YQL без успеха я все еще учусь этому, нибудь есть су ggestions

Если проблема не из-за множества вложенных апострофов и незамкнутая двойные кавычки, то наиболее вероятной причиной (мы можем только догадываться, не будучи показан документ XML) является то, что используется пространство имен по умолчанию ,

Указание имен элементов, которые находятся в пространстве имен по умолчанию, является наиболее часто задаваемым вопросом в XPath. Если вы ищете «пространство имен XPath по умолчанию» в SO или в Интернете, вы найдете много источников с правильным решением.

Как правило, необходимо вызвать специальный метод, который связывает префикс (например, "x:") с пространством имен по умолчанию. Затем в выражении XPath каждое имя элемента "someName" должно быть заменено на "x:someName.

good answer how to do this in C#.

Прочитайте документацию вашего языка/xpath-engine, как нечто подобное должно быть сделано в вашей конкретной среде.

3

Я думаю, у меня есть решение, которое не требует иметь дело с пространствами имен.

Вот один, который выбирает все соответствующие ДИВ-х:

//div[@id[starts-with(.,"post_message")]] 

Но вы сказали, что вы хотели только «первый» (я предполагаю, что вы имеете в виду первый «удар» по всей странице?). Вот небольшая модификация, которая выбирает только первый результат согласования:

(//div[@id[starts-with(.,"post_message")]])[1] 

Они используют точку, чтобы представлять значение идентификатора в пределах функции starts-with(). Возможно, вам придется скрывать специальные символы на вашем языке.

Он отлично работает для меня в PowerShell:

# Load a sample xml document 
$xml = [xml]'<root><div id="post_message_somenumber"/><div id="not_post_message"/><div id="post_message_somenumber2"/></root>' 

# Run the xpath selection of all matching div's 
$xml.selectnodes('//div[@id[starts-with(.,"post_message")]]') 

Результат:

id 
-- 
post_message_somenumber 
post_message_somenumber2 

Или, только первый матч:

# Run the xpath selection of the first matching div 
$xml.selectnodes('(//div[@id[starts-with(.,"post_message")]])[1]') 

Результат:

id 
-- 
post_message_somenumber 
1
@FindBy(xpath = "//div[starts-with(@id,'expiredUserDetails') and contains(text(), 'Details')]") 
private WebElementFacade ListOfExpiredUsersDetails; 

Это один дает список всех элементов на странице, которые разделяют идентификатор expiredUserDetails, а также содержит текст или элемент Details

Смежные вопросы