Question

Can somebody help me find an xPath, that would locate an element based on its text, which is split across several spans? When I use text() function, it seems to only find the starting sequence of the element text until the first span.

For example in a following scenario I would like to locate only the first <h5> and not the other one. That is to find an element, which displays a text "A xxx B"

...
<h5>
A
<span>xxx</span>
B
</h5>
...
<h5>
A
<span>xxx</span>
C
</h5>
Was it helpful?

Solution 3

You can match all h5 and only copy / do whatever with the nodes, if they meet a certain condition. This condition is to check the last text node (or [2] for second), whether it is equal to some hardcoded string. You may need to use normalize-space() to eleminate whitespace from the text node:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <xsl:output method="xml" indent="yes"/>

  <xsl:template match="/">
    <result>
      <xsl:apply-templates select="root/h5"/>
    </result>
  </xsl:template>


  <xsl:template match="h5">
    <xsl:if test="normalize-space(./text()[last()]) = 'C'">
      <xsl:copy-of select="."/>
    </xsl:if>
  </xsl:template>
</xsl:stylesheet>

Result:

<?xml version="1.0" encoding="utf-8"?>
<result>
  <h5>
    A
    <span>xxx</span>
    C
  </h5>
</result>

OTHER TIPS

Try this:

h5[1]

You can select a certain item of a collection by using an index.

Use descendant-or-self::node() to get the whole text from the h5 tag, handle newlines and spaces with normalize-space():

//h5[normalize-space(descendant-or-self::node()) = 'A xxx B']

Demo (using xmllint):

$ xmllint index.html --xpath "//h5[normalize-space(descendant-or-self::node()) = 'A xxx B']"
<h5>
    A
    <span>xxx</span>
    B
</h5>

where index.html contains:

<div>
    <h5>
        A
        <span>xxx</span>
        B
    </h5>
    ...
    <h5>
        A
        <span>xxx</span>
        C
    </h5>
</div>

Similar situation:

<button title="Create New" accesskey="N">
Create
<span class="X">N</span>
ew
</button>

It create button with text "Create New". To find this button you can use

 //button[descendant-or-self::* = 'Create New']

This is simpler version of alecxe answer (if you don't have space inside)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top