Kevin
Kevin

Reputation: 6831

Test for Node Emptiness

I have the following two xml nodes:

<CELL ROWSPAN="1" COLSPAN="3">
  <TableBodyCenterBold>
    <A ID="pgfId-179932"/>
  </TableBodyCenterBold>
</CELL>

<CELL ROWSPAN="1" COLSPAN="6">
  <TableBodyCenterBold>
    <A ID="pgfId-179938"/>
    Body Tensile Capacity (lb)
  </TableBodyCenterBold>
</CELL>

Apparently, the first node <CELL> differs from the second <CELL> in that the <TableBodyCenterBold> of the first one doesn't have any text.

I have tried the following XPath, but all failed:

<xsl:when test="string-length(CELL[1]/TableBodyCenterBold[1]/text()) &gt; 0">

or

<xsl:when test="CELL[1]/TableBodyCenterBold[1]/text()!=''">

Could experts offer some help on how to efficiently differentiate the first node from the second?

Upvotes: 2

Views: 159

Answers (3)

krakover
krakover

Reputation: 3029

Try

CELL[1]/TableBodyCenterBold[1]/A[not(text())]

or

CELL[1]/TableBodyCenterBold/A[not(node())]

Upvotes: 1

Dimitre Novatchev
Dimitre Novatchev

Reputation: 243509

You must take into account the existing white-space - only text-node children of TableBodyCenterBold.

A correct expression that tests for "emptyness" and ignores whitespace-only text nodes is:

CELL[1]/TableBodyCenterBold[1][not(string-length(normalize-space()) > 0)] 

This evaluates to true() exactly when the first TableBodyCenterBold child of the first CELL child of the current node, has a string value, which when normalized results in the empty string.

Upvotes: 2

Todd Ditchendorf
Todd Ditchendorf

Reputation: 11337

Krakover's answer is the right idea, but I believe he's erroneously included the A node-test step. I believe you are instead looking for:

CELL[1]/TableBodyCenterBold[not(text())]

The text in your example is inside the TableBodyCenterBold element, not the A element.

Also, since this is a relative XPath (it doesn't start with /), you might double-check that this XPath is being evaluated against the context node you were expecting.

Upvotes: 1

Related Questions