0

I have a parent element (font) and I would like to select all the child elements (direct descendants) that are either text() or span elements. How would I construct such an xpath?

0

1 Answer 1

3

If the current node is the font element, then something like this:

text()|span

otherwise you have to always combine with | the two complete XPath - the one for text and the one for span, e.g.:

font/text()|font/span

if the current node is just above font - or

//a[text()='View Larger Map']/../../../../div[contains(@class, 'paragraph')][3]/font/span|//a[text()='View Larger Map']/../../../../div[contains(@class, 'paragraph')][3]/font/text()

if starting from the root with some complex selection criteria.

If you have complex paths like the last one probably it is better to store a partial one in a variable - e.g. inside an XSLT:

<xsl:variable name="font" select="//a[text()='View Larger Map']/../../../../div[contains(@class, 'paragraph')][3]/font"/>

. . . 

<xsl:for-each select="$font/span|$font/text()">
  . . . 
</xsl:for-each>

Another possibility is to do something like this:

//a[text()='View Larger Map']/../../../../div[contains(@class, 'paragraph')][3]/font/node()[name()='span' or name()='']

that works because name() returns an empty string for text() nodes - but I am not 100% sure that it works that way for all XPath processors, and it could match by mistake comment nodes.

Sign up to request clarification or add additional context in comments.

4 Comments

Do I need some parens or something similar because if I try "//a[text()='View Larger Map']/../../../../div[contains(@class, 'paragraph')][3]/font/span|text()", I get the child span (but no text elements) and if I do "//a[text()='View Larger Map']/../../../../div[contains(@class, 'paragraph')][3]/font/text()|span", I get the text elements but no span. Thanks for any clarifications
Comment nodes also don't have a name. Therefore, this answer needs to be corrected. The document node (root node) is another type of node that has no name, but it is safe to be ommitted from consideration in this specific case.
@DimitreNovatchev: I wrote '...and it could match by mistake comment nodes' - the second solution can be used only if you are sure that there are no commentsw in the source, the first one should work always.
@MiMo: Yes. What I said in my comment is that it isn't acceptable to provide a solution that is problematic and point out its problems. Much better is to fix this problematic solution and provide the fixed solution -- and this is possible in this particular case.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.