How abouts:
p/*[not(local-name()='br')]
And then index that expression for whatever term you want
EDIT:
For your indexing issue:
p/*[not(local-name()='br') and position() < x and position() > y]
How abouts:
p/*[not(local-name()='br')]
And then index that expression for whatever term you want
EDIT:
For your indexing issue:
p/*[not(local-name()='br') and position() < x and position() > y]
Try using the position() or maybe the count() methods. Here's a guess that might help you get the right syntax.
p/*[position() > position(/p/br[1]) and position() < position(/p/br[2])]
EDIT: Please read the comments before voting or commenting.
If in your situation you always have exactly three 'pieces', separated by br
s, you can use this XPath to get the middle 'piece':
//node()[preceding::br and following::br]
which uses the preceding
and following
axes to return all nodes between two br
s, anywhere at all.
edit this is my test app (please excuse the XmlDocument
, I am still working with .NET 2.0...)
using System;
using System.Xml;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
XmlDocument doc = new XmlDocument();
doc.LoadXml(@"
<x>
<h3>Section title</h3>
<p>
<b>Component A</b><br />
Component B <i>includes</i> <strong>multiple elements</strong><br />
Component C
</p>
</x>
");
XmlNodeList nodes = doc.SelectNodes(
"//node()[preceding::br and following::br]");
Dump(nodes);
Console.ReadLine();
}
private static void Dump(XmlNodeList nodes)
{
foreach (XmlNode node in nodes)
{
Console.WriteLine(string.Format("-->{0}<---",
node.OuterXml));
}
}
}
}
And this is the output:
-->
Component B <---
--><i>includes</i><---
-->includes<---
--><strong>multiple elements</strong><---
-->multiple elements<---
As you can see, you get an XmlNodeList
with all the stuff between the br
s.
The way I think about it is: This XPath returns any node anywhere, so long as for that node, the preceding axis contains a br
, and the following axis contains a br
.
This can easily be done with XPath 2.0 or with XPath 1.0 hosted by XSLT.
With XPath 1.0 hosted by .NET this can be achieved in several steps:
Make the appropriate "p" node the current node.
Find the number of all <br />
children of the current "p" node:
count(br)
if N is the count, determined in step 2. for $k in 0
to N
do:
3.1 Find all nodes that are preceded by $k <br />
elements:
node()[not(self::br) and count(preceding::br) = $k]
3.2 For every such node found, get its string value
3.3 Concatenate all string values obtained in step 3.2. The result of this concatenation is all the text contained in the given paragraph.
Note: In order to substitute what should stand for $k
in step 3.1 it is necessary to dynamically construct this expression.