Как выполнить итерации через элементы DOM, которые соответствуют классу CSS с помощью xpath?

Я обрабатываю страницу HTML с переменным числом p элементов с классом CSS "myclass", с помощью Python + Селен RC.

Когда я пытаюсь выбрать каждый узел с этим xpath:

//p[@class='myclass'][n]

(с n натуральное число)

Я получаю только первый p элемент с этим классом CSS для каждого n, в отличие от ситуации, если я выполняю итерации посредством выбора ВСЕХ p элементов с:

//p[n]

Есть ли какой-либо способ, которым я могу выполнить итерации через элементы классом CSS с помощью xpath?

9
задан Prasad 14 August 2012 в 15:27
поделиться

4 ответа

XPath 1.0 не предоставляет итерирующую конструкцию.

Итерация может быть выполнена над выбранным набором узлов в языке, на котором размещен XPath.

Примеры:

В XSLT 1.0:

   <xsl:for-each select="someExpressionSelectingNodes">
     <!-- Do something with the current node -->
   </xsl:for-each>

В C#:

using System;
using System.IO;
using System.Xml;

public class Sample {

  public static void Main() {

    XmlDocument doc = new XmlDocument();
    doc.Load("booksort.xml");

    XmlNodeList nodeList;
    XmlNode root = doc.DocumentElement;

    nodeList=root.SelectNodes("descendant::book[author/last-name='Austen']");

    //Change the price on the books.
    foreach (XmlNode book in nodeList)
    {
      book.LastChild.InnerText="15.95";
    }

    Console.WriteLine("Display the modified XML document....");
    doc.Save(Console.Out);

  }
}

XPath 2. 0 имеет свою собственную итерационную конструкцию:

   for $varname1 in someExpression1,
       $varname2 in someExpression2, 
      .  .  .  .  .  .  .  .  .  .  .
       $varnameN in someExpressionN 
    return
        SomeExpressionUsingTheVarsAbove
1
ответ дан 5 December 2019 в 02:07
поделиться

Я не думаю, что вы используете "указатель" по прямому назначению. Синтаксис // p [selection] [index] в этом выделении фактически сообщает вам, каким элементом в его родительском элементе он должен быть ... Итак // p [selection] [1] говорит, что выбранный вами p должен быть первым потомком своего родителя. // p [selection] [2] говорит, что это должен быть второй ребенок. В зависимости от вашего HTML, скорее всего, это не то, что вам нужно.

Учитывая, что вы используете Selenium и Python, есть несколько способов делать то, что вы хотите, и вы можете просмотреть этот вопрос , чтобы увидеть их (там есть два варианта, один из которых связан с селеном). Javascript, другой использует вызовы селена на стороне сервера).

0
ответ дан 5 December 2019 в 02:07
поделиться

Возможно, все ваши div с этим классом находятся на одном уровне, поэтому по //p[@class='myclass'] вы получаете массив параграфов с указанным классом. Поэтому вы должны перебирать его, используя индексы, т.е. //p[@class='myclass'][1], //p[@class='myclass'][2],...,//p[@class='myclass'][last()]

0
ответ дан 5 December 2019 в 02:07
поделиться

Вот фрагмент кода на C#, который может вам помочь.

Ключевой здесь является функция Selenium GetXpathCount(). Она должна вернуть количество вхождений искомого выражения Xpath.

Вы можете ввести //p[@class='myclass'] в XPather или любой другой инструмент анализа Xpath, чтобы вы могли убедиться, что возвращается несколько результатов. Затем вы просто перебираете результаты в своем коде.

В моем случае нужно было итерировать все элементы списка в UL - т.е. //li[@class='myclass']/ul/li - поэтому, исходя из ваших требований, должно получиться что-то вроде:

int numProductsInLeftNav = Convert.ToInt32(selenium.GetXpathCount("//p[@class='myclass']"));

List<string> productsInLeftNav = new List<string>();
for (int i = 1; i <= numProductsInLogOutLeftNav; i++) {
    string productName = selenium.GetText("//p[@class='myclass'][" + i + "]");
    productsInLogoutLeftNav.Add(productName);
}
0
ответ дан 5 December 2019 в 02:07
поделиться