2010-11-01 28 views
3

J'utilise sélénium avec Perl et avoir une étiquette sur la page, pour accéder à cette étiquette j'ai xpath suivant: //*[text()='some here'], le problème que le besoin d'obtenir xpath complet de cet élément, comme /html/body/table/tr/..../any other/and other/, est il y a une méthode au sélénium ou une fonction perl? Vous cherchez une solution perl ou d'autres choses de travail.Get XPath complet de partielle

grâce

+0

Bonne question, +1. Voir ma réponse pour un template XSLT 1.0 universel qui produit une expression XPath pour n'importe quel noeud de n'importe quel type. –

Répondre

1

à la recherche d'une solution de Perl ou tout autre choses travail

Cette XPath 2.0 expression:

string-join(for $node in ancestor-or-self::node() 
      return concat(('@')[$node/self::attribute()], 
          $node/name(), 
          (concat('[', 
            count($node/preceding-sibling::node() 
              [name()=$node/name()]) + 1, 
            ']'))[$node/../node() 
              [name()=$node/name()][2]]), 
      '/') 

Modifier: Shorter expression.

1

Cette transformation XSLT 1.0 produit une expression XPath pour chaque noeud contenu dans le paramètre $pNode:

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

<xsl:template match="node()|@*"> 
    <path> 
    <xsl:call-template name="buildPath"/> 
    </path> 
    <xsl:apply-templates select="node()|@*"/> 
</xsl:template> 


<xsl:template name="buildPath"> 
<xsl:variable name="pNode" select="."/> 
    <xsl:variable name="theResult"> 
    <xsl:for-each select="$pNode"> 
    <xsl:variable name="theNode" select="."/> 
    <xsl:for-each select= 
    "$theNode 
    | 
    $theNode/ancestor-or-self::node()[..]"> 
     <xsl:element name="slash">/</xsl:element> 
     <xsl:choose> 
     <xsl:when test="self::*"> 
      <xsl:element name="nodeName"> 
      <xsl:value-of select="name()"/> 
      <xsl:variable name="thisPosition" select= 
      "count(preceding-sibling::* 
        [name(current()) 
        = 
        name()])"/> 
      <xsl:variable name="numFollowing" select= 
      "count(following-sibling:: 
        *[name(current()) 
        = 
         name()])"/> 
      <xsl:if test="$thisPosition + $numFollowing > 0"> 
       <xsl:value-of select= 
       "concat('[', $thisPosition +1, ']')"/> 
      </xsl:if> 
      </xsl:element> 
     </xsl:when> 
     <xsl:otherwise> <!-- This node is not an element --> 
      <xsl:choose> 
      <xsl:when test="count(. | ../@*) = count(../@*)"> 
      <!-- Attribute --> 
       <xsl:element name="nodeName"> 
       <xsl:value-of select="concat('@',name())"/> 
       </xsl:element> 
      </xsl:when> 
      <xsl:when test="self::text()"> <!-- Text --> 
       <xsl:element name="nodeName"> 
       <xsl:value-of select="'text()'"/> 
       <xsl:variable name="thisPosition" 
          select="count(preceding-sibling::text())"/> 
       <xsl:variable name="numFollowing" 
          select="count(following-sibling::text())"/> 
       <xsl:if test="$thisPosition + $numFollowing > 0"> 
        <xsl:value-of select= 
        "concat('[', $thisPosition +1, ']')"/> 
       </xsl:if> 
       </xsl:element> 
      </xsl:when> 
      <xsl:when test="self::processing-instruction()"> 
      <!-- Processing Instruction --> 
       <xsl:element name="nodeName"> 
       <xsl:value-of select="'processing-instruction()'"/> 
       <xsl:variable name="thisPosition" 
        select="count(preceding-sibling::processing-instruction())"/> 
       <xsl:variable name="numFollowing" 
        select="count(following-sibling::processing-instruction())"/> 
       <xsl:if test="$thisPosition + $numFollowing > 0"> 
        <xsl:value-of select= 
        "concat('[', $thisPosition +1, ']')"/> 
       </xsl:if> 
       </xsl:element> 
      </xsl:when> 
      <xsl:when test="self::comment()"> <!-- Comment --> 
       <xsl:element name="nodeName"> 
       <xsl:value-of select="'comment()'"/> 
       <xsl:variable name="thisPosition" 
         select="count(preceding-sibling::comment())"/> 
       <xsl:variable name="numFollowing" 
         select="count(following-sibling::comment())"/> 
       <xsl:if test="$thisPosition + $numFollowing > 0"> 
        <xsl:value-of select= 
        "concat('[', $thisPosition +1, ']')"/> 
       </xsl:if> 
       </xsl:element> 
      </xsl:when> 
      <!-- Namespace: --> 
      <xsl:when test= 
       "count(. | ../namespace::*) 
       = 
       count(../namespace::*)"> 

       <xsl:variable name="apos">'</xsl:variable> 
       <xsl:element name="nodeName"> 
       <xsl:value-of select="concat('namespace::*', 
       '[local-name() = ', $apos, local-name(), $apos, ']')"/> 

       </xsl:element> 
      </xsl:when> 
      </xsl:choose> 
     </xsl:otherwise> 
     </xsl:choose> 
    </xsl:for-each> 
    <!-- <xsl:text>&#xA;</xsl:text> --> 
    </xsl:for-each> 
</xsl:variable> 
<xsl:value-of select="$theResult"/> 
</xsl:template> 
</xsl:stylesheet> 

lorsqu'il est appliqué sur le document XML suivant:

<div id="entry-1" class="item-asset asset hentry"> 
    <div class="asset-header"> 
    <h2 class="asset-name entry-title"> 
     <a rel="bookmark" href="http://blahblah.com/paper-scissors">Paper Scissors</a> 
    </h2> 
    </div> 
    <div class="asset-content entry-content"> 
    <div class="asset-body"> 
    <p>Paper and scissors</p> 
    </div> 
    </div> 
</div> 

le résultat est une liste des expressions XPath pour chaque noeud du document:

<path>/div</path> 
<path>/div/@id</path> 
<path>/div/@class</path> 
<path>/div/div[1]</path> 
<path>/div/div[1]/@class</path> 
<path>/div/div[1]/h2</path> 
<path>/div/div[1]/h2/@class</path> 
<path>/div/div[1]/h2/a</path> 
<path>/div/div[1]/h2/a/@rel</path> 
<path>/div/div[1]/h2/a/@href</path> 
<path>/div/div[1]/h2/a/text()</path> 
<path>/div/div[2]</path> 
<path>/div/div[2]/@class</path> 
<path>/div/div[2]/div</path> 
<path>/div/div[2]/div/@class</path> 
<path>/div/div[2]/div/p</path> 
<path>/div/div[2]/div/p/text()</path> 
+0

+1 Bonne réponse! –

+0

Eh bien, mais comment utiliser ce XSLT 1.0? – CODERED

+0

@CODERED: Vous pouvez appeler le template 'buildPath' quand vous en avez besoin dans votre code avec n'importe quel paramètre (noeud) auquel vous voulez accéder. Utilisez simplement l'instruction ''. Par exemple, vous pouvez passer le noeud sélectionné par la première expression comme paramètre à l'appel de 'buildPath'. –