Difference between XmlDocumentFragment and XmlNode in .Net - c#

I don't understand the difference between XmlDocumentFragment and XmlNode.
I understand that the first one is a derived type of the second one.
Why is it better to use XmlDocumentFragment to create or edit the nodes of an XmlDocument in the code ?

I found answer here:
DocumentFragment is a "lightweight" or "minimal" Document object. It
is very common to want to be able to extract a portion of a document's
tree or to create a new fragment of a document. Imagine implementing
a user command like cut or rearranging a document by moving fragments
around. It is desirable to have an object which can hold such
fragments and it is quite natural to use a Node for this purpose.
While it is true that a Document object could fulfil this role, a
Document object can potentially be a heavyweight object, depending on
the underlying implementation. What is really needed for this is a
very lightweight object. DocumentFragment is such an object.
Furthermore, various operations -- such as inserting nodes as children
of another Node -- may take DocumentFragment objects as arguments;
this results in all the child nodes of the DocumentFragment being
moved to the child list of this node. The children of a
DocumentFragment node are zero or more nodes representing the tops of
any sub-trees defining the structure of the document. DocumentFragment
nodes do not need to be well-formed XML documents (although they do
need to follow the rules imposed upon well-formed XML parsed
entities, which can have multiple top nodes). For example, a
DocumentFragment might have only one child and that child node could
be a Text node. Such a structure model represents neither an HTML
document nor a well-formed XML document. When a DocumentFragment is
inserted into a Document (or indeed any other Node that may take
children) the children of the DocumentFragment and not the
DocumentFragment itself are inserted into the Node. This makes the
DocumentFragment very useful when the user wishes to create nodes that
are siblings; the DocumentFragment acts as the parent of these nodes
so that the user can use the standard methods from the Node
interface, such as insertBefore() and appendChild().

Related

Traversing/comparing tree structures with only parent references

Consider a tree structure with nodes containing references to only their parent. So, the root node's parent will be null. This tree represents a class hierarchy. The goal is to search such a tree for a particular subtree, and if it doesn't exist, add it to the tree. Is there an algorithm that can be used to achieve this?
In this particular case, I have a C# WinForms application which uses this kind of structure. At the moment, an iterative breadth-first traversal is being used to traverse through such a tree and display it as a treeView. How this is being done is as follows: To represent the nodes of the tree itself, there is a class Data_Node. To perform the traversal, the nodes are placed into a queue. The queue contains instances of a data structure, QueueNode:
private class QueueNode
{
public Model.Data_node dataNode; // actual tree node
public QueueNode parent; // reference to the parent
public TreeNode treeNode; // node for treeView in the UI
}
The next step is to implement another such tree (assume it is already, then check whether it is a subtree of the first one, and add it if it is not.
I have researched examples of what I am trying to achieve, but they were only for binary search trees, with nodes having references to the child nodes. In my case, the nodes only have references to the parent node.

Syntax rewriting

I need to transform all of the properties of a certain class using Roslyn.
What is the recommended way to apply more than one transformation to a syntax tree without invalidating references into it?
Here is what I've tried and where I'm stuck:
In the first pass a descendant of CSharpSyntaxWalker is visiting all PropertyDeclarationSyntax nodes, and storing them in a list.
In the second pass a CSharpSyntaxRewriter is transforming the nodes while checking that each visited node equals one in the list before transforming it.
The problem with my attempt is: When I transform a property I add new fields to the class which causes the class to mutate. All the references in the list to the other properties become invalid in the new tree for the class.
It seems to be inefficient to revisit the whole class, and either way I cannot detect the property nodes already handled due to the reference difference.
I would not recommend to reference nodes from a SyntaxTree you want to modify. In your case just using a CSharpSyntaxRewriter in a single pass (without keeping references from a pre-processing pass) would be sufficient, because its VisitPropertyDeclaration method will only be called once per property, so there is no need to keep track of the nodes you've already modified.
The CSharpSyntaxRewriter also visits the nodes bottom-up, so the overrides should always be called with a node from the original tree. Most likely you have modified the node through the call to base.VisitPropertyDeclaration() before comparing its reference to the stored one. So you could still keep and compare references if you really wanted to.
public class PropertyRewriter : CSharpSyntaxRewriter
{
public override SyntaxNode VisitPropertyDeclaration(PropertyDeclarationSyntax node)
{
// 'node' should be still from the original syntax tree here
node = (PropertyDeclarationSyntax)base.VisitPropertyDeclaration(node);
// 'node' might be replaced here
return node;
}
}
Instead of keeping references to the nodes you want to modify, you could annotate them. Annotations to a node will survive modifications of the containing SyntraxTree as long as the node itself isn't replaced. You can add them like this:
node = node.WithAdditionalAnnotations(
new SyntaxAnnotation("propertyToChange", "todo"));
To retrieve the annotation again either use node.GetAnnotations("propertyToChange") or use GetAnnotatedNodesOrTokens("propertyToChange") to retrieve all nodes or tokens with an annotation of the given kind ("propertyToChange").

should a tree have exactly one root node

I want to display a tree structure. Do i really need to give the user/tree a predefined hardcoded root node like "RootUnit" where he can add his children or descendants?
Does this make sense or cause only trouble when adding nodes?
If you have two roots then you have two trees.
A tree should have only one root. But you need not hardcode a root. Just treat the first created tree node as root.
A tree by definition has only one root and every child node has exactly one parent (except the root which has no parent). If these restrictions are not met then your tree is no longer a tree but a graph (oriented or not)
It depends on the context. From a strict mathematical definition, you cannot have multiple root nodes to a tree. However, there some implementations of trees that ignore that and have multiple top level nodes anyway (Such as the TreeView control you tagged this question with). You simply need to ask yourself if your particular program would be better or worse with multiple top level nodes. Given that we know nothing else about your program it's not a decision we can really make for you.
Rather than using the same constructor for every node, supply a default constructor used for the root node and one for everything else. It isn't ugly, and it works.
public Node()
{
// Set properties if you'd like.
// such as having no children yet or whatnot.
}
public Node(Node parent)
{
// Similar to Node()
}
See! Nice and clean.

Class design to contain data from an XML file

I'm a student working on a lab that parses a pseudo XML file(basically coded our own parser) for data, stores the retrieved elements and data values, and displays (next lab will be adding "add,change,delete" functionality)
I was thinking about holding this read in information in some sort of multidimensional List due to it being dynamic by default. The other suggestion I've read over some other questions here at SO is to make a "parent node" class, and just store that in an array.
The problem I have is that at code time there is no way to know for sure how many child nodes a parent node will have. It could be --
<parent>
<child1>data value</child1>
<child2>data value</child2>
...etc
</parent>
or
<parent>
<child1data value</child1>
</parent>
I can't really think how I could code a class to have an unknown amount of variables.
Why not just use a List<List<T>>? Or maybe a Dictionary<string, List<T>>, assuming your parent nodes have unique identifiers?
You can keep a list of nodes or a dictionary of nodes if the nodes are unique in some way.
.NET collections are inherently dynamic. You don't need to know in advance how many items your collection will hold. A collection of your own class "parent" would work. Each parent class itself would implement a collection of "children". You can define them to be anything you want.
Even better though would be to make your class serializable from the get go, so that when you save it to an XML file it's already in a properly formatted XML structure. Reading in that data would require deserialization and it would populate everything for you. Check this out.
You should manage by your self but just think, you have parent as root and parent has list of child. Where is problem ? :)

.NET tree object model

I like Microsoft's Windows Forms tree-view object model. It has the tree, nodes, children collection, parent, prev, next (sibling), etc. and search function. However I'm looking for the same object model with no UI - simply tree object model.
Does C# have this kind of model or do I have to implement it myself?
C# is a programming language. It does not have object models.
You may be asking whether the .NET Framework has a built-in "tree" class. It does not. You can build your own using the generic collection classes like LinkedList<T> and List<T>.
You could always use XML and the XML namespaces. It's got all the things you requested. Start with and XMLDocument and keep added XMLNodes and adding XMLNodes to the XMLNodes for children. Then you can use xpath queries to retrieve nodes.
An XmlDocument object is the closest match I can think of to your requirements. It supports parent, child, previous, next, sibling, etc. You can also use XPath to query the tree and return a specific node or sets of nodes. Also, because it's Xml you can easily import and export the data to/from a text file.
I suggest you read about binary trees on MSDN. It will teach you how to model tree data structures in code.
Good luck.

Categories

Resources