2012-05-27 4 views
1

Я Scrapy & новичок Xpath, и я ищу для синтаксического анализа веб-сайт со следующей структуройВыбрать все д.Д. тег до нового дл тега с Xpath

<dl class="ismSummary ismHomeSummary"> 
     <dt>cat1</dt> 
      <dd>value1</dd> 
      <dd>value2</dd> 
     <dt>cat2</dt> 
      <dd>value1</dd> 
      <dd>value2</dd> 
</dl> 

С Xpath Я только хочу, чтобы получить value1 & значение2 (в dd «s) из cat1

Это то, что я прямо сейчас

//dt[text()="cat1"]/following-sibling::dd 

проблема заключается в том, что не улица op at cat2 и продолжить выбирать значение1 & value2 из cat2. :(

+0

Syl, Вы получили одно выражение XPath, который выбирает именно разыскиваемых узлов. Вместо этого вы решили принять более сложное, не переносимое и менее ремонтируемое решение, которое требует не только оценки XPath, но и дополнительного кода на языке хоста. –

ответ

3

Все узлы здесь дети dl, поэтому, естественно, все братья и сестры первого dt, поэтому, когда вы используете following-sibling вы получаете их все.

Xpath было сделано с XML в виду, и в XML вас вероятно, будет иметь dd элементы, как дети dt, но, к сожалению, это не тот случай.

Самый простой способ woule быть просто включают все братские dt (а не только dd с) и перебирать результат не установлен до тех пор, dt. Использование функции Xpath для d o сделать то же самое, что возможно, но, безусловно, более сложно.

+0

+1 простой и pythonic – gauden

2

Применение:

//dt[. = 'cat1'] 
    /following-sibling::dd 
     [count(.| //dt[. = 'cat2']/preceding-sibling::dd) 
     = 
     count(//dt[. = 'cat2']/preceding-sibling::dd) 
     ] 

При условии, что //dt[. = 'cat1'] и //dt[. = 'cat2'] каждый выбор оны одного элемента, приведенное выше выражение выбирает именно те хотело два dd элементов.

XSLT - на основе проверки:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 

<xsl:template match="/"> 
    <xsl:copy-of select= 
    "//dt[. = 'cat1'] 
    /following-sibling::dd 
     [count(.| //dt[. = 'cat2']/preceding-sibling::dd) 
     = 
     count(//dt[. = 'cat2']/preceding-sibling::dd) 
     ] 

    "/> 
</xsl:template> 
</xsl:stylesheet> 

Когда это преобразование применяется на прилагаемом документе XML (со значениями последних двух dd с измененными, поэтому мы знаем наверняка, что хотел элементы выбраны):

выражение
<dl class="ismSummary ismHomeSummary"> 
    <dt>cat1</dt> 
    <dd>value1</dd> 
    <dd>value2</dd> 
    <dt>cat2</dt> 
    <dd>value3</dd> 
    <dd>value4</dd> 
</dl> 

XPath вычисляется и п оды он выбирает копируются на выход:

<dd>value1</dd> 
<dd>value2</dd> 

Объяснение:

Здесь мы используем метод Kayessian для пересечения множество узлов в XPath 1.0:

Пересечение двух множеств узлов: $ns1 и $ns2 является:

$ns1[count(.|$ns2) = count($ns2)] 

В нашем случае мы заменим $ns1 с:

//dt[. = 'cat1']/following-sibling::dd 

и подставим $ns2 с:

//dt[. = 'cat2']/preceding-sibling::dd 
Смежные вопросы