Exclude node during searches

Questions about XML that are not covered by the other forums should go here.
jorusso
Posts: 4

Exclude node during searches

Fri Dec 06, 2013 10:12 am

I'm in DITA and my goal is to search for text that is not inside a particular element. For example I want to search for "ABC Corp." that is not inside <codeblock>. I should be able to specify any of the following Xpath statements:

    //*[(name()!='codeblock')]
    //*[not(self::codeblock)]
    //*[not(codeblock)]

All of these give the expected results in the XPath field on the toolbar. However, none of them work when I use them in the XPath field in the Find dialog box.

What am I doing wrong?
Jamil
Posts: 77

Re: Exclude node during searches

Sat Dec 07, 2013 3:47 pm

I had never used the XPath input on the find dialog. It could very well be an issue with it.

What you could do instead is write an XQuery to show you what you are looking for. The Saxon extensions for it can show the line numbers of the XML document.
jorusso
Posts: 4

Re: Exclude node during searches

Mon Dec 09, 2013 9:34 pm

Thanks, Jamil.

I've been looking for an excuse to study XQuary, anyway!
So having a real-world need is perfect. :shock:
adrian
Posts: 2451

Re: Exclude node during searches

Fri Dec 13, 2013 4:42 pm

Hello,

The problem with the XPath expressions you're using is that even though they exclude the codeblock element, they don't exclude any of codeblock's parent elements. Find will search in the most extensive range selected by the XPath (it merges the XPath results), which in all cases for your expressions includes the root element and everything in it.
So, in short the expressions you are using don't filter what you want.

If you want to search only within text that is not inside <codeblock>, you could specify that clearly in the XPath expression:

Code: Select all

//text()[not(ancestor::codeblock)]

Or if you want to also search across multiple (text) nodes (e.g. text with markup) you can use in the XPath field:

Code: Select all

//*[not(descendant-or-self::codeblock)]|//text()[not(ancestor::codeblock)]


XQuery is pretty powerful, but you'll still need XPath there as well.

Regards,
Adrian
Adrian Buza
<oXygen/> XML Editor, Schema Editor and XSLT Editor/Debugger
http://www.oxygenxml.com
jorusso
Posts: 4

Re: Exclude node during searches

Thu Feb 13, 2014 2:26 am

Adrian,

Thanks for the helpful reply! Sorry it took so long to reply, I forgot to log back in to check for a reply.

Can you offer any recommendations on learning XPath? I've done the W3 tutorial and know just enough to get myself in trouble!

-joe
adrian
Posts: 2451

Re: Exclude node during searches

Thu Feb 13, 2014 6:51 pm

Hi,

Unfortunately most online tutorials are for the beginner level, so they overlap a lot.
You could also give zvon.org a try:
http://zvon.org/comp/r/tut-XPath_1.html

As usual, experience is the best teacher, so you should try various things on your own. When something doesn't work as you expect it, search the web for answers.

Regards,
Adrian
Adrian Buza
<oXygen/> XML Editor, Schema Editor and XSLT Editor/Debugger
http://www.oxygenxml.com
shudson310
Posts: 128
Location: USA

Re: Exclude node during searches

Thu Jun 07, 2018 2:28 am

Here's a related question:

We want to find:

Code: Select all

<wintitle>some text</wintitle>


and replace with:

Code: Select all

<wintitle keyref="someKey" />


We've tried restricting the XPath to:

Code: Select all

//*[not(descendant-or-self::alt|descendant-or-self::title|descendant-or-self::shortdesc|descendant-or-self::draft-comment)]|//text()[not(ancestor::alt|ancestor::title|ancestor::shortdesc|ancestor::draft-comment)]


Unfortunately, we are still getting results within shortdesc, so the exclusion doesn't appear to work. I think this is due to the fact that we are trying to modify an element node and turn it into a keyref.

Any suggestions on how to search/replace across files with the exclusions we're trying to achieve?
Scott Hudson
Content Strategist
Jeppesen
Site: jeppesen.com
adrian
Posts: 2451

Re: Exclude node during searches

Thu Jun 07, 2018 11:17 am

Hi,

There is a mistake in my XPath (from 4 years ago) that covers elements and text (for text with markup). It should be:

Code: Select all

//*[not(descendant-or-self::codeblock|ancestor::codeblock)]|//text()[not(ancestor::codeblock)]
This way it won't accept
So, try this one (note that you don't need the //text if you're searching markup):

Code: Select all

//*[not(descendant-or-self::alt|descendant-or-self::title|descendant-or-self::shortdesc|descendant-or-self::draft-comment|ancestor::alt|ancestor::title|ancestor::shortdesc|ancestor::draft-comment)]

Regards,
Adrian
Adrian Buza
<oXygen/> XML Editor, Schema Editor and XSLT Editor/Debugger
http://www.oxygenxml.com
shudson310
Posts: 128
Location: USA

Re: Exclude node during searches

Thu Jun 07, 2018 3:40 pm

That worked perfectly. Thanks for the quick, expert help!
Scott Hudson
Content Strategist
Jeppesen
Site: jeppesen.com

Return to “General XML Questions”

Who is online

Users browsing this forum: No registered users and 1 guest