简体   繁体   中英

XPath conditional text node selection

I need to construct an xpath string to select all descendants of a certain table with these conditions:

  • The table is a descendant of a form with a specific action attribute value.
  • The selected descendants are text nodes.
  • The text node content can only contain whitespace.

It'll probably look something like:

//form[@action = "submit.html"]//table//text()[ ...? ]

Any tips would be appreciated. Thanks.

Edit: Here is my previous working compromise:

function KillTextNodes(rootpath)
{
    XPathIterate(rootpath + '//text()', function(node)
    {
        var tagname = node.parentNode.tagName;
        if (tagname != 'OPTION' && tagname != 'TH')
            Kill(node);
    });
}

Here is my function based on the accepted answer:

function KillTextNodes(rootpath)
{
    XPathIterate(rootpath + '//text()[not(normalize-space())]', function(node) { Kill(node); });
}

To explain my motivation a little - I'm iterating through the DOM with Javascript, and run into the same problem that many others do where unexpected empty text nodes throw off the results. This function helps me out a lot by simply deleting all of the empty text nodes so that my iteration logic can stay simple.

Hi there. I need to construct an xpath string to select all descendants of a certain table with these conditions:

•The table is a descendant of a form with a specific action attribute value.

•The selected descendants are text nodes.

•The text node content can only contain whitespace.

Use :

//form[@action = "submit.html"]//table//text()[not(normalize-space())]

This selects all text nodes that have only white-space in them and that are descendents of any table that is a descendent of any form having an action attribute with value "submit.html".

Text nodes containing whitespace only will be stripped from the document representation - ie there won't actually be a node. That means you can't access the text itself, but what you can do is match a parent lacking a text node using not() - something like:

//form[@action = "submit.html"]//table//*[not(text())]

Though in your case I would guess that will be far more aggressive than you actually intend. As an aside, be careful with these // matches, they're not very efficient and again very aggressive.

(I've just noticed this isn't an XSLT question! If you're in JS land have you considered using DOM methods to get your list?)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM