Jeets
Jeets

Reputation: 3377

Using XPath expression how can i get the first text node immediately following a node?

I want to get to the exact node having this text: 'Company'. Once I get to this node I want to get to the next text node immediately following this node because this contains the company name. How can I do this with Xpath?

Fragment of XML is:

<div id="jobsummary">
    <div id="jobsummary_content">
        <h2>Job Summary</h2>
        <dl>
            <dt>Company</dt>
            <!-- the following element is the one I'm looking for -->
            <dd><span class="wrappable">Pinpoint IT Services, LLC</span></dd>
            <dt>Location</dt>
            <dd><span class="wrappable">Newport News, VA</span></dd>
            <dt>Industries</dt>
            <dd><span class="wrappable">All</span></dd>
            <dt>Job Type</dt>
            <dd class="multipledd"><span class="wrappable">Full Time</span></dd><dd class="multipleddlast"><span class="wrappable"> Employee</span></dd>
        </dl>
    </div>
</div>

I got to the Company tag with following xpath: //*[text()= 'Company'] Now I want to get to the next text node. My XML is dynamic. So I can't hardcode the node type like <dd> for getting the company value. But this is for sure that the value be in the immediate next text node.

So how can I get to the text node immediately after the node with text as Company?

Upvotes: 5

Views: 4322

Answers (4)

Dimitre Novatchev
Dimitre Novatchev

Reputation: 243549

Use this general XPath expression that selects the wanted text node even when it is wrapped in statically unknown markup elements:

(//*[text()='Company']/following-sibling::*[1]//text())[1]

When this XPath expression is evaluated against the provided XML document:

<div id="jobsummary">
    <div id="jobsummary_content">
        <h2>Job Summary</h2>
        <dl>
            <dt>Company</dt>
            <!-- the following element is the one I'm looking for -->
            <dd><span class="wrappable">Pinpoint IT Services, LLC</span></dd>
            <dt>Location</dt>
            <dd><span class="wrappable">Newport News, VA</span></dd>
            <dt>Industries</dt>
            <dd><span class="wrappable">All</span></dd>
            <dt>Job Type</dt>
            <dd class="multipledd"><span class="wrappable">Full Time</span></dd><dd class="multipleddlast"><span class="wrappable"> Employee</span></dd>
        </dl>
    </div>
</div>

exactly the wanted text node is selected:

Pinpoint IT Services, LLC

Even if we change the XML to this one:

<div id="jobsummary">
    <div id="jobsummary_content">
        <h2>Job Summary</h2>
        <div>
            <p>Company</p>
            <!-- the following element is the one I'm looking for -->
            <dd><span class="wrappable"><b><i><u>Pinpoint IT Services, LLC</u></i></b></span></dd>
            <dt>Location</dt>
            <dd><span class="wrappable">Newport News, VA</span></dd>
            <dt>Industries</dt>
            <dd><span class="wrappable">All</span></dd>
            <dt>Job Type</dt>
            <dd class="multipledd"><span class="wrappable">Full Time</span></dd><dd class="multipleddlast"><span class="wrappable"> Employee</span></dd>
        </div>
    </div>
</div>

the XPath expression above still selects the wanted text node:

Pinpoint IT Services, LLC

Upvotes: 0

Filburt
Filburt

Reputation: 18082

If you cannot hardcode any part of the following-sibling node your xpath should look like this:

//*[text()='Company']/following::*/*/text()

assuming that the desired text is always enclosed in another element like span.


To test for given dt text, modify your xpath to

//*[text()='Company' or text()='Company:' or text()='Company Name']/following::*/*/text()

Upvotes: 3

Pankaj
Pankaj

Reputation: 2754

You can Use XPathNavigator and go on to every node type one by one

I think XPathNavigator::MoveToNext is the method you are looking for.

There is the sample code as well at.. http://msdn.microsoft.com/en-us/library/9yxc3x24.aspx

Upvotes: 0

CosminO
CosminO

Reputation: 5226

use //*[text()='Company']/following-sibling::dd to get the next dd.

You can even insert conditions for that dd and also go further in it. following-sibling::elementName just looks for the next sibling at the same parent level that meets your requirements. With no conditions, like above, it will get the next dd after the 'Company'.

The text is in the span so you might try

//*[text()='Company']/following-sibling::dd/span

Another clarifying example would be, let's say that you want to get also the next industries text for the current selected 'Company'.

Having //*[text()='Company',

you can modify it like this: //*[text()='Company']/following-sibling::dt[text()='Industries']/dd/span

Of course, instead of hardcoding the values for text(), you can use variables.

Upvotes: 0

Related Questions