472,133 Members | 1,168 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 472,133 software developers and data experts.

How to tell if XmlNode is part of document tree

I have a container of XmlNodes. Some of them have been removed from
the document, some haven't. Is there an easy way to tell which are
which?

I suppose
bool IsPartOfTree(XmlNode node)
{
while (node.ParentNode != null) { node = ParentNode; }
return node == node.OwnerDocument;
}
would work, but it doesn't seem elegant.

Jan 23 '07 #1
7 2316
ma**********@yahoo.co.uk wrote:
bool IsPartOfTree(XmlNode node)
{
while (node.ParentNode != null) { node = ParentNode; }
Should be
while (node.ParentNode != null) { node = node.ParentNode; }
I guess.
return node == node.OwnerDocument;
}
would work, but it doesn't seem elegant.
I don't think there is any method exposed that you could use so that
walk of the ParentNode hierarchy is not too bad.

If you don't want to use the loop you can use XPath e.g.

public static bool IsPartOfDocumentTree (XmlNode node) {
return node.SelectSingleNode(@"ancestor::node()") ==
node.OwnerDocument;
}

--

Martin Honnen --- MVP XML
http://JavaScript.FAQTs.com/
Jan 23 '07 #2
Martin Honnen wrote:
ma**********@yahoo.co.uk wrote:
bool IsPartOfTree(XmlNode node)
{
while (node.ParentNode != null) { node = node.ParentNode; }
[snip correction - thanks!]
return node == node.OwnerDocument;
}
would work, but it doesn't seem elegant.

I don't think there is any method exposed that you could use so that
walk of the ParentNode hierarchy is not too bad.
Thanks. Sigh. (I suppose there isn't much that an API could do, other
than duplicate the loop).
If you don't want to use the loop you can use XPath e.g.

public static bool IsPartOfDocumentTree (XmlNode node) {
return node.SelectSingleNode(@"ancestor::node()") ==
node.OwnerDocument;
}
Hmm. That seems like a sledgehammer to crack a nut. It also feels
hairy applying XPath to something that isn't (part of) a full document.

(On a different topic - I really dislike the way that
SelectNodes/SelectSingleNode ignores the axis ordering. I think I
would make the XPath expression:
"ancestor::node()[last()]"
which ought to accurately select the top of the tree.)

Jan 23 '07 #3
Why are you walking up the parent tree to look for the OwnerDocument? All
descendant nodes, not just the root, reference the parent document. For
instance, the following (assuming my source document had enough children to
return nodes from the XPath) would output the owning document's ToString for
each node:
foreach (XmlNode node in
myDocument.SelectNodes("//*[1]/*[1]/*"))
{
System.Diagnostics.Debug.WriteLine(node.OwnerDocum ent);
}
Jan 23 '07 #4
Keith Patrick wrote:
Why are you walking up the parent tree to look for the OwnerDocument?
Because he needs to find out whether walking up the parent hierarchy he
finds the OwnerDocument as an ancestor or not to check whether the node
he started with is included in the tree rooted by the OwnerDocument or
in an orphan subtree detached from the OwnerDocument.
--

Martin Honnen --- MVP XML
http://JavaScript.FAQTs.com/
Jan 23 '07 #5
On Jan 23, 2:18 pm, martinfro...@yahoo.co.uk wrote:
I have a container of XmlNodes. Some of them have been removed from
the document, some haven't. Is there an easy way to tell which are
which?

I suppose
bool IsPartOfTree(XmlNode node)
{
while (node.ParentNode != null) { node = ParentNode; }
return node == node.OwnerDocument;
}
would work, but it doesn't seem elegant.
Oops. There are in fact TWO problems with the above code. Firstly, as
Martin Nonnen points out below, it should be:
node = node.ParentNode;
secondly, the OwnerDocument property of the document node returns null.
So the final test should be:
return (node.NodeType == XmlNodeType.Document);

So, in case somebody wants the full code, it should be:
public static bool IsPartOfDocumentTree (XmlNode node)
{
while (node.ParentNode != null)
{
node = node.ParentNode;
}
return (node.NodeType == XmlNodeType.Document);
}

(Note: The above has still not been compiled, let alone tested!)

Jan 24 '07 #6
I've never had a detached subtree still retain its reference to the original
document, so that's what I'm not seeing. Is he saying that when RemoveNode
is called, the doc reference remains?

Jan 24 '07 #7
Using the Kaysian method for intersection of node-sets the intersection is
non-empty if and only if:
count($ns1[count(.|$ns2) = count($ns2)]) 0

We can use this to tell whether two nodes belong to the same document, by
defining the two node-sets as the sets of ancestors of each of the given
nodes:

Therefore, two nodes belong to the same document if and only if:
count($node1/ancestor::node()[count(.|$node2/ancestor::node()) =
count($node2/ancestor::node()) ]) 0

To answer your specific question, represent the document by the document
node (or by the top element) in the above XPath expression.

This was tested successfully with the XPath Visualizer and it is confirmed
that the above expression returns 'true' only in the case when the two nodes
belong to the same XML document

Cheers,
Dimitre Novatchev

<ma**********@yahoo.co.ukwrote in message
news:11**********************@q2g2000cwa.googlegro ups.com...
>I have a container of XmlNodes. Some of them have been removed from
the document, some haven't. Is there an easy way to tell which are
which?

I suppose
bool IsPartOfTree(XmlNode node)
{
while (node.ParentNode != null) { node = ParentNode; }
return node == node.OwnerDocument;
}
would work, but it doesn't seem elegant.

Jan 25 '07 #8

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

1 post views Thread by Michael Hutchinson | last post: by
1 post views Thread by Owen Blacker | last post: by
5 posts views Thread by Paul | last post: by
5 posts views Thread by Mahesh Devjibhai Dhola | last post: by
reply views Thread by Philip Wagenaar | last post: by
7 posts views Thread by Sharon | last post: by
reply views Thread by =?Utf-8?B?ZGF2aWQ=?= | last post: by

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.