HTML XPath - Как получить XPath элемента на основе значения другого элемента? - PullRequest
2 голосов
/ 08 марта 2011

У меня есть следующий HTML-код:

<table>
<tbody>
    <tr>
        <th class="colhead" nowrap="nowrap">Update</th>
        <th class="colhead" nowrap="nowrap">Card No</th>
    </tr>
    <tr>
        <td nowrap="nowrap"><a href="/admin?cpm_id=1043">
        Update</a></td>
        <td nowrap="nowrap">4987 6543 2109 8769</td>
    </tr>
    <tr>
        <td nowrap="nowrap"><a href="/admin?cpm_id=905">
        Update</a></td>
        <td nowrap="nowrap">5123 4567 8901 2346</td>
    </tr>
</tbody>

У меня вопрос: если я знаю значение элемента «Нет карты», как я могу получить XPath по ссылке «Обновить»? Например, если я знаю, что номер карты равен «5123 4567 8901 2346», как я могу получить XPath элемента ссылки "<a href="/admin?cpm_id=905">"?

Обновление от комментариев

Я использую инструмент для автоматизации тестирования называется QTP. Мне нужно получить XPath элемент ссылки обновления для его идентификации на веб-странице на основе значения номер кредитной карты. Что я после это получить XPath такой как "/ HTML / тело / таблицы / TBODY / TR [3] / тд [1] / A". Тем не менее, это статический путь элемент ссылки обновления. мне бы хотелось чтобы иметь возможность получить XPath на основе Номер кредитной карты.

Ответы [ 3 ]

1 голос
/ 08 марта 2011

Это не сложная задача для XSLT :

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output method="text"/>
 <xsl:strip-space elements="*"/>

 <xsl:param name="pCardNo" select=
 "'5123 4567 8901 2346'"/>

 <xsl:template match="/">
  <xsl:variable name="vNode" select=
  "/*/*/tr[td[2] = $pCardNo]/td[1]
                     /a/ancestor-or-self::*"/>

  <xsl:apply-templates select="$vNode" mode="path"/>
 </xsl:template>

 <xsl:template match="*" mode="path">
  <xsl:value-of select="concat('/',name())"/>

  <xsl:variable name="vnumPrecSiblings" select=
    "count(preceding-sibling::*[name()=name(current())])"/>

  <xsl:variable name="vnumFollSiblings" select=
    "count(following-sibling::*[name()=name(current())])"/>

  <xsl:if test="$vnumPrecSiblings or $vnumFollSiblings">
   <xsl:value-of select=
      "concat('[', $vnumPrecSiblings +1, ']')"/>
  </xsl:if>
 </xsl:template>

</xsl:stylesheet>

, когда это преобразование применяется к предоставленному документу XML:

<table>
    <tbody>
        <tr>
            <th class="colhead" nowrap="nowrap">Update</th>
            <th class="colhead" nowrap="nowrap">Card No</th>
        </tr>
        <tr>
            <td nowrap="nowrap">
                <a href="/admin?cpm_id=1043">         Update</a>
            </td>
            <td nowrap="nowrap">4987 6543 2109 8769</td>
        </tr>
        <tr>
            <td nowrap="nowrap">
                <a href="/admin?cpm_id=905">         Update</a>
            </td>
            <td nowrap="nowrap">5123 4567 8901 2346</td>
        </tr>
    </tbody>
</table>

желаемый, правильный результат получается:

/table/tbody/tr[3]/td[1]/a
0 голосов
/ 03 февраля 2012

Наткнулся на концепцию, называемую букмарклетами.Использование заданных букмарклетов в вашем HTML-коде привело к результату, /HTML/BODY/TABLE/TBODY/TR[3]/TD[1]/A.

URL-адрес Эквивалент Firebug's CopyXPath "в Internet Explorer?

Выполнение закладок для полей редактирования имени и электронной почты на этой странице приводит к

//INPUT[@id='display-name']

//INPUT[@id='m-address']

Надеюсь, это поможет

0 голосов
/ 08 марта 2011

Ответ Димитре хорош для XSLT-решения, но для полноты излагаем еще одну перспективу. Поскольку данные находятся в таблице с однородной структурой, в некотором смысле XPath для любого одного элемента совпадает с , если рассматривать номер карты в качестве параметра. Например, в C # метод string.Format использует {0} в качестве заполнителя, как показано в XPATH_TEMPLATE ниже. Просто заполните заполнитель в этом шаблоне номером карты, чтобы получить необходимое выражение XPath.

string XPATH_TEMPLATE = 
  "//td[normalize-space(.)='{0}']/preceding-sibling::td/a";
string CardNumber = "4987 6543 2109 8769";
string XPathExpression = string.Format(XPATH_TEMPLATE, CardNumber);

Выше приведено следующее результирующее выражение XPath:

//td[normalize-space(.)='4987 6543 2109 8769']/preceding-sibling::td/a

Итак, работаете ли вы в XSLT, C # или чем-то еще, этот вариант XPath более значим (чем, например, / table / tbody / tr [3] / td [1] / a), поскольку он самодостаточен с контекстная информация.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...