HTML XPath - 如何根据另一个元素的值获取元素的XPath?

时间:2011-03-08 01:28:53

标签: html xslt xpath

我有以下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>

我的问题是,如果我知道'Card No'元素的价值,我怎样才能获得Update链接的XPath?例如,如果我知道卡号是“5123 4567 8901 2346”,我如何获得链接元素"<a href="/admin?cpm_id=905">"的XPath?

从评论中更新

  

我正在使用自动化测试工具   叫做QTP。我需要获得XPath   用于标识它的更新链接元素   在网页上基于的价值   信用卡号码。我在追求什么   是得到XPath这样的   为 “/ HTML /体/表/ tbody的/ TR [3] / TD [1] /一种”。   但是,这是静态路径   更新链接元素。我想要   能够基于a获得XPath   信用卡号码。

3 个答案:

答案 0 :(得分:1)

对于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

答案 1 :(得分:0)

Dimitre的答案适用于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)因为它是自包含的背景信息。

答案 2 :(得分:0)

超越了名为bookmarklets的概念。使用HTML代码上的给定bookmarklet生成结果,/ HTML / BODY / TABLE / TBODY / TR [3] / TD [1] / A.

网址为Equivalent of Firebug's "Copy XPath" in Internet Explorer?

在此页面上的名称和电子邮件编辑框中执行书签会生成

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

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

希望这有帮助