Dex graph database retrieve all nodes and edges - c#

I know how I can output my graph database to a file (like a GraphML file), but I'd rather iterate through the nodes and have them as C# objects because I need to use them elsewhere.
Something like this:
var it = graph.GetNodeIterator();
while (it.HasNext()) {
var node = new MyNodeObject();
//get attributes or whatever
nodeList.Add(node);
}
//nodeList now contains all nodes in a List
I can't find a convenient way to do this and the Dex documentation isn't very helpful. Clearly Dex has some way of doing this because I can easily export to GraphML, but I don't want to export to GraphML and then parse the GraphML into C# objects.

Here is how I do it, not sure if it's the best way though:
//find the type(s) youre looking for based on how you assigned
//them in the first place. you may already know.
var typeIt = graph.FindTypes().Iterator();
while (typeIt.HasNext()) {
//find your types if you dont know
}
//select the types you want. lets say all of your nodes have one of two types,
//which map to attributes 4 and 3.
var select = graph.Select(4);
//union them
select.Union(graph.Select(3));
//start to iterate
var it = select.Iterator();
while (it.HasNext()) {
var next = it.Next();
//map to your own objects using next
}

Related

Tabular Editor: How to use advanced scritpting to create multiple measures based on one value and one category column

I am trying to create multiple measures in Power BI through advanced scripting in Tabular editor that would replicate a Calculate(Sum(ColA),Keepfilters(ColB=i))
I understand that i would need a for loop and iterate over the values in ColB but i dont manage the iterating over the values in ColB.
How do i do that?
There is an ExecuteReader method available in Tabular Editor scripts, which returns an IDataReader-object that you can use to iterate the result. To add one measure for every value in a column, you would need to do something like this (inspired by this example):
using(var reader = ExecuteReader("EVALUATE VALUES(MyTable[ColB])");
{
while(reader.Read())
{
var colBvalue = reader.GetString(0); // Assumes [ColB] contains strings, otherwise use .GetInt64, .GetDecimal, .GetDouble, etc...
var measureName = string.Format("Measure filtered by {0}", colBvalue);
var measureDax = string.Format("CALCULATE(SUM(MyTable[ColA]), KEEPFILTERS(MyTable[ColB]=\"{0}\"))", colBvalue);
Model.Tables["MyTable"].AddMeasure(measureName, measureDax);
}
}

C# List Sort vs Inserting

I have a list of objects which I sort multiple times throughout code and when the user interacts with the program. I was wondering if it would be better to insert new items into the list rather than add to the end of the list and resort the entire list.
The code below is for importing browser bookmarks - Here I add a bunch of bookmarks to the List (this._MyLinks) which are Link objects and then sort the final List - Which I think is probably best in this given scenario....
public void ImportBookmarks(string importFile)
{
using (var file = File.OpenRead(importFile))
{
var reader = new NetscapeBookmarksReader();
var bookmarks = reader.Read(file);
foreach (var b in bookmarks.AllLinks)
{
bool duplicate = this._MyLinks.Any(link => link._URL == b.Url);
if(duplicate)
{
continue;
}
Link bookmark = new Link();
bookmark._URL = b.Url;
bookmark._SiteName = b.Title;
bookmark.BrowserPath = "";
bookmark.BrowserName = "";
if (bookmark.AddToConfig(true))
{
this._MyLinks.Add(bookmark);
}
}
}
this._MyLinks = this._MyLinks.OrderBy(o => o._SiteName).ToList();
}
Now a user also has the option to add their own links (one at a time). Whenever the user adds a link the ENTIRE list is sorted again using
this._MyLinks = this._MyLinks.OrderBy(o => o._SiteName).ToList();
Is it better from a preformance standpoint (or just generally) to just insert the item directly into it's specified location? If so would you have suggestions on how I can go about doing that?
Thanks!
Since you want a sorted set of data you should be using a more appropriate data structure, specifically a sorted data structure, rather than using an unsorted data structure that you re-sort every time, or that forces you to inefficiently add items to the middle of a list.
SortedSet is specifically designed to maintain a sorted set of data efficiently.

What is the optimal way to store data from HTML table?

I am currently reading in an HTML document using CsQuery. This document has several HTML tables and I need to read in the data while preserving the structure. At the moment, I simply have a List of List of List of strings. This is a list of tables containing a list of rows containing a list of cells containing the content as a string.
List<List<List<string>>> page_tables = document_div.Cq().Find("TABLE")
.Select(table => table.Cq().Find("TR")
.Select(tr => tr.Cq().Find("td")
.Select(td => td.InnerHTML).ToList())
.ToList())
.ToList();
Is there a better way to store this data, so I can easily access particular tables, and specific rows and cells? I'm writing several methods that deal with this page_tables object so I need to nail down its formulation first.
Is there a better way to store this data, so I can easily access particular tables, and specific rows and cells?
On most occassions, well-formed HTML fits nicely into an XML structure so you could store it as an XML document. LINQ to XML would make querying very easy
XDocument doc = XDocument.parse("<html>...</html>");
var cellData = doc.Descendant("td").Select(x => x.Value);
Based on the comments I feel obliged to point out that there are a couple of other scenarios where this can fall over such as
When HTML-encoded content like is used
Valid HTML which doesn't require a closing tag e.g. <br> is used
(With that said, these things can be handled by some pre-processing)
To summarise, it's by all means not the most robust approach, however, if you can be sure that the HTML you are parsing fits the bill then it would be a pretty neat solution.
You could go fully OOP and write some model classes:
// Code kept short, minimal ctors
public class Cell
{
public string Content {get;set;}
public Cell() { this.Content = string.Empty; }
}
public class Row
{
public List<Cell> Cells {get;set;}
public Row() { this.Cells = new List<Cell>(); }
}
public class Table
{
public List<Row> Rows {get;set;}
public Table() { this.Rows = new List<Row>(); }
}
And then fill them up, for example like this:
var tables = new List<Table>();
foreach(var table in document_div.Cq().Find("TABLE"))
{
var t = new Table();
foreach(var tr in table.Cq().Find("TR"))
{
var r = new Row();
foreach(var td in tr.Cq().Find("td"))
{
var c = new Cell();
c.Contents = td.InnerHTML;
r.Cells.Add(c);
}
t.Rows.Add(r);
}
tables.Add(t);
}
// Assuming the HTML was correct, now you have a cleanly organized
// class structure representing the tables!
var aTable = tables.First();
var firstRow = aTable.Rows.First();
var firstCell = firstRow.Cells.First();
var firstCellContents = firstCell.Contents;
...
I'd probably choose this approach because I always prefer to know exactly what my data looks like, especially if/when I'm parsing from external/unsafe/unreliable sources.
Is there a better way to store this data, so I can easily access
particular tables, and specific rows and cells?
If you want to easily access table data, then create class which will hold data from table row with nicely named properties for corresponding columns. E.g. if you have users table
<table>
<tr><td>1</td><td>Bob</td></tr>
<tr><td>2</td><td>Joe</td></tr>
</table>
I would create following class to hold row data:
public class User
{
public int Id { get; set; }
public string Name { get; set; }
}
Second step would be parsing users from HTML. I suggest to use HtmlAgilityPack (available from NuGet) for parsing HTML:
HtmlDocument doc = new HtmlDocument();
doc.Load("index.html");
var users = from r in doc.DocumentNode.SelectNodes("//table/tr")
let cells = r.SelectNodes("td")
select new User
{
Id = Int32.Parse(cells[0].InnerText),
Name = cells[1].InnerText
};
// NOTE: you can check cells count before accessing them by index
Now you have collection of strongly-typed user objects (you can save them to list, to array or to dictionary - it depends on how you are going to use them). E.g.
var usersDictionary = users.ToDictionary(u => u.Id);
// Getting user by id
var user = usersDictionary[2];
// now you can read user.Name
Since your parsing an HTML table. Could you use an ADO.Net DataTable? If the content doesn't have too many row or col spans this may be an option, you wouldn't have to roll your own and it could be easily saved to a database or list of entities or whatever. Plus you get the benefit of strongly typed data types. As long as the HTML tables are consistent I would prefer an approach like this to make interoperability with the rest of the framework seamless and a ton less work.

How to skip attributes when converting an XML file into a Dataset displayed with DataGridView

As stated in my question,
i have a XML file that outputs as follows:
<cme Type="Object" Class="cme">
<sId Type="String">1</sId>
<conc Type="Double">18,6511073619</conc>
</cme>
<cme Type="Object" Class="cme">
<sId Type="String">2</sId>
<conc Type="Double">18,3226889524</conc>
</cme>
<cme Type="Object" Class="cme">
<sId Type="String">3</sId>
<conc Type="Double">4,7920021996</conc>
</cme>....
I created a new Form in Visual Studio and there added the following code:
cmDataSet.ReadXml(filePath,XmlReadMode.InferSchema);
cmDataGrid.DataSource = cmDataSet;
cmDataGrid.AutoGenerateColumns = true;
cmDataGrid.DataMember = "cme"; <-- Parent Node
But when the form is displayed, while the number of rows matches the count,
the cells are filled with the values of the attributes, and NOT the real values, in this way:
Object cme
Object cme
Object cme
Object cme
How do I skip the attributes from being evaluated to display the real values only?
I believe you need to create xsd schema for your xml file. And add cmDataSet.ReadXmlSchema call to code:
cmDataSet.ReadXmlSchema(xsdFilePath);
cmDataSet.ReadXml(filePath, XmlReadMode.InferSchema);
cmDataGrid.DataSource = cmDataSet;
cmDataGrid.AutoGenerateColumns = false;
cmDataGrid.DataMember = "cme"; <-- Parent Node
You need schema, because currently dataset will hold 3 DataTables: cme, sId and conc. Which is not what you are looking for.
Actually, if xml file have no schema it is as good and easy to work with as with an "angle bracket separated text".
Another approach is to use LINQ to XML and construct anonymous object (or create strongly typed object and map to it) that will represent your data grid row:
var doc = XDocument.Load(filePath);
var rows = doc.Root.Elements("cme")
.Select(e => new
{
cId = e.Element("sId").Value,
conc = e.Element("conc").Value
});
cmDataGrid.DataSource = rows.ToList();
cmDataGrid.AutoGenerateColumns = true;
Using LINQ projections is a quick and easy way to display data but you can lose a lot of time during implementation of the "add/update/edit row" scenarios.

How to create an object from a single item from an xml file using linq?

Basically I have a single element inside of an xml file where I store settings for my application. This element mirrors a class that I have built. What I'm trying to do using LINQ, is select that single element, and then store the values stored inside of that element into an instance of my class in a single statement.
Right now I'm selecting the element seperately and then storing the values from that element into the different properties. Of course this turns into about six seperate statements. Is it possible to do this in a single statement?
It will be better if you can show your XML but you can get general idea from code below
XDocument doc = //load xml document here
var instance = from item in doc.Descendants("ElementName")
select new YourClass()
{
//fill the properties using item
};
You can use LINQ to XML, e.g.
var document = XDocument.Load("myxml.xml");
document.Element("rootElement").Element("myElement").Select(e =>
new MySettingsClass
{
MyProperty = e.Attribute("myattribute").Value,
MyOtherProperty = e.Attribute("myotherattribute").Value
});
See http://msdn.microsoft.com/en-us/library/bb387098.aspx for more details.

Categories