Treeview insert property problem - c#

TreeNode[] nodes = this.treeview.Nodes.Find(node.Text, true);
if (nodes.Length > 0)
{
int i = nodes[0].Index;
if (nodes.Length > 0)
this.treeview.Nodes.Remove(nodes[0]);
this.treeview.Nodes.Insert(i, nodes[0]);
}
i tried this code,
but the node nodes[0] is not inserting into the particular index.
instead it is adding at the last.
but yes i use treeviewsorter.
Any idea how to insert node without using insert
or using insert effectively with treeviewsorter??

If you have set the TreeViewNodeSorter property to a custom comparer, your TreeView nodes will automatically be sorted using that comparer.
Thus, you can't insert a node in a different position, because the position is decided using the comparer.
But, in your specific case you're removing a node and inserting it back in its original position, and you say it doesn't work when actually it should do.
This, (I'm guessing) could be due to several reasons:
Your comparer implementation is wrong, or peraphs it uses a property that depends on the sorting itself (like Node.Index)
The node you get with Find() (supposing is just one...), belongs to a level lower than root, but you try to remove it from root nodes and add to that level...
Other reasons, we need more code...

Related

DiffBuilder - ignore element value but make sure the XML node is present

I am using DiffBuilder to compare two XML files.
For the given element Product, I want to check that the element is present but I want to ignore its value.
Is it possible using XmlUnit ?
My code below will work regardless of the presence of the Product element, which doesn't work for what I need
var differenceBuilder = DiffBuilder
.Compare(Input.FromDocument(controlXmlFile))
.WithTest(Input.FromDocument(testXmlDile))
.WithNodeFilter(n => n.Name != "Product");
In this case you don't want to throw away the node itself but the differences between the nodes. You wouldn't use a NodeFilter but rather a DifferenceEvaluator for this.
A very simplified version could be something like
.WithDifferenceEvaluator((comparison, outcome) =>
comparison.ControlDetails.Target.Name == "Product" ? ComparisonResult.EQUAL : outcome
)
but you'd need to take into account that ControlDetails could be null (and look at TestDetails instead) for example. And if your Product node has child elements you may want to either filter them out with NodeFilter or check whether any parent of the current comparison target is named Product.

RavenDB and Recursive Includes

I have a structure
class Node {
List<string> ChildrenIds;
...
}
That I currently store and lookup in RavenDB but Include for results only lets me include down one level in the potentially many leveled tree. Is there any way to tell it to lookup recursively all of these Nodes referenced from the top level?
I know indexes can be used recursively but I wasn't clear on how best to use that to load the correct documents, is it possible to somehow do an Include on an index property?
Yes, you use the JS support in the query, like so:
declare function recursiveInclude(n){
for(var i = 0; i<n.ChildrenIds.length; i++)
recursiveInclude(load(n.ChildrenIds[i]));
return n;
}
from Node as n
select recursiveInclude(n)

Trying to do Unwind and Create New Relationship Between Nodes Neo4J C# Client

I have a list of nodes - In the code as targetNodeList and I have a node called sourceNode(Different Types Of Nodes).
The List and the single node are already existing in the neo4j Db
and I would like to make a relationship between them with additional data that is inside the targetNodeList.
TargetNodeList is a wrapper which contains the node data and the relationship data that I would like to put inside the Relationship
I havn't manage to finish the code because I don't know how to continue it but thats the sample that I tried to do :
public void CreateRelationshipBetweenNodes(NodeType sourceNode,List<TargetNodes> targetNodeList,int solutionId)
{
graphClient.Cypher
.Unwind(targetNodeList, "singleNode")
.Match("(firstNode:FirstType)", "(secondNode:SecondType)")
.Where(" firstNode.Id = otherNode:FirstType{Id:innerNode.Id}")
.AndWhere(" secondNode.Id = node:SecondType {Id:singleNode.Id}")
.WithParams(new { innerNode = sourceNode})
.Create("(firstNode)-[msg:SENT {solution}]->(secondNode)")
.WithParam("solution", solutionId).ExecuteWithoutResults();
}
its not working and there is still more data that I want to add to the relationship from the singleNode for example: singleNode.Score
Would appriciate any help.
Thanks a lot from advanced.
So I'm a little confused with the nodes you're taking in and how they relate, but hopefully the below query will get you on the right route.
First off, match on the sourceNode then UNWIND your other nodes, ready to do the create. Once you have the two nodes MATCHed you then CREATE the relationship (PS. you may want MERGE if you don't want duplicates) - and I set an Id property on the relationship - you need to provide a property name, else it won't work!
graphClient.Cypher
.Match("(sourceNode:SourceNodeType {Id:sourceNode.Id})")
.Unwind(targetNodeList, "singleNode")
.Match("(targetNodeInDb:TargetNode {Id:targetNode.Id})")
.Create("(sourceNode)-[:SENT {Id:{solutionIdParam}}]->(targetNode)")
.WithParam("solutionIdParam", solutionId)
.ExecuteWithoutResults();

Remove an XElement from another XDocument

I need to remove an XElement from a XDocument.
The problem is i can't just use the .Remove() because my XDocument is not the same as the XElement.
A very important fact is performance.
Scenario: I have an XDocument docSource and I copy this to XDocument doc. I select a Node of docSource and want to delete this Node in my doc.
So far I'm using this workaround (which may also delete some wrong nodes if they got the same Parent Name but this doesn't matter so far):
private static XNode actualNode;
private static void RemoveNode(XDocument doc)
{
doc.Root.Descendants(((XElement)actualNode).Name.LocalName)
.Where(e => actualNode.Parent.Name.LocalName.Equals(e.Parent.Name.LocalName))
.Remove();
}
Is there a better way to do this? And especially a faster way?
My XDocument has like 1000 lines.
Well a better way of doing the existing name-based approach would be:
doc.Root.Descendants(actualNode.Parent.Name)
.Elements(actualNode.Name)
.Remove();
Aside from anything else, that's simpler - and doesn't use just the local name. (If the elements are actually in different namespaces, you should take account of that separately IMO.)
But this is still just using "element name and parent name" as a way of identifying an element. Do you have anything else which will identify the element more reliably? Some kind of attribute? I'm assuming you actually have some idea of what kind of element you'll be finding.
My XDocument has like 1000 lines.
Then it should be blink-of-an-eye quick anyway. Do you actually have any indication that this is causing a performance problem?
Another thing to consider:
Scenario: I have an XDocument docSource and I copy this to XDocument doc. I select a Node of docSource and want to delete this Node in my doc.
Is there any reason you don't just avoid copying the node to start with?
As you have rightly said, if you just rely on the Parent.Name.LocalName you may end up deleting incorrect child nodes when there are Parents with similar names.
If you validate for repeated parent nodes before deleting the child nodes you will be able to over come this issue.
You should be able to achieve accuracy by loading the nodes to an array/list. Then you will be able to find the position of the exact parent node. But I am afraid it will not improve the performance.
For an example you have 3 parent nodes with 'XZY'.
User selects the 2 parent node. So your parent index will be 1(assuming the index starts with 0)
So you should only delete the children under parent index 1.
Hope this helps.

Order HtmlNodes Based on their position on the HTML Page (C# / XPath)

Context:
I am parsing the result of a Query on this service, but the HTML with the result is a mess.
My goal is the build a "KeyValue" pair with each "attribute and value" shown as result of this query.
At the moment only one way came into my mind to solve it.
Logic for Parsing:
Select all the Attribute nodes
Select all the value nodes
Match their "indexes" on each collection built to build the Key Value Pairs
E.g: Attribute[0] with Value[0] -> (In this service, that would be "CNPJ" and "12.272.084/0001-00").
Problem:
Even tho i managed to find a XPath expression to fetch all the attributes nodes:
attrNodes = htmlDoc.DocumentNode.SelectNodes ("//td[#bgcolor='#f1f1b1']/*/font[#face='Verdana']");
I could not manage to find one for the value nodes aswell, since there are different types of nodes that actually look the same when rendered by Html ( "b" and "strong" for example).
There are even nodes with different hierarquies that prevented me from using Wildcards ("*") on XPath to solve it (single tag or two tags nested for example)
My Goal:
Write XPaths to reach each different subset of nodes with values
Put all the nodes in a single Collection
Order the nodes of this Collection based on the position of each node in the Html (nodes that appear first on the HTML will be on the begining of the list)
Any idea of how can i achieve my goal ?
HTML Sample:
You can either give it a check here
or Query yourself the service by typing : 12272084000100 on the CNPJ textbox
and clicking on "Pesquisar". After that, you just have to click on the text "Companhia Eletrica de Alagoas"
Thanks in Advance
I just found an Attribute that can be found on the "HtmlNode" class of the HtmlAgilityPack Framework that managed to solve my problem.
According to this documentation about the HtmlNode Class:
StreamPosition
Gets the stream position of this node in the document, relative to the start of the document.
Here is the output of my tests using a list of tables found in this very same Html Page (tables used for testing purposes)
// HtmlNodeCollection of Tables
tableNodes[0].StreamPosition
925
tableNodes[1].StreamPosition
1651
tableNodes[2].StreamPosition
2387
Ordering my list using this StreamPosition as parameter managed to solve my problem.
List<HtmlNode> OrderedList = valueNodes.OrderBy ( node => node.StreamPosition ).ToList<HtmlNode>();

Categories