I try to explain my problem:
Okay, I need the KSCHL and the Info.
I need the KSCHL from the result file and then I want to search after the KSCHL in the other file "Data".
In the first file I have all KSCHL.
var kschlResultList = docResult.SelectNodes(...);
var kschlDataList = docData.SelectNodes(...);
var infoDataList = docData.SelectNodes(...);
for (int i = 0; i < kschlResultList.Count; i++)
{
string kschlResult = kschlResultList[i].InnerText;
for (int x = 0; x < kschlDataList.Count; x++)
{
string kschlData = kschlDataList[x].InnerText;
if (kschlData == kschlResult)
{
for (int y = 0; y < infoDataList.Count; y++)
{
string infoData = infoDataList[y].InnerText;
if (infoData == kschlResult)
{
//I know the If is false
string infoFromKschl = infoData;
}
}
}
}
}
The problem is now to find the KSCHL (from the first file) in the second file and then to search after the "info".
So if I have the KSCHL "KVZ1" in the first file, then I want to search this KSCHL in the second file and the associated Info for it.
Hope you understand :)
You don't have to loop quite so much. :-)
Using XPath - the special strings inside SelectNodes() or SelectSingleNode(), you can go pretty directly to what you want.
You can see a great basic example - several really - of how to select an XML node based on another node at the same level here:
How to select a node using XPath if sibling node has a specific value?
In your case, we can get to a list of the INFO values more simply by looping just through the KSCHL values. I use them as text, because I want to make a new XPath string with them.
I'm not clear exactly what format you want the results in, so I'm simply pushing them into a SortedDictionary for now.
At that last step, you could do other things as is most useful to you..... such as push them into a database, dump them in a file, send them to another function.
/***************************************************************
*I'm not sure how you want to use the results still,
* so I'll just stick them in a Dictionary for this example.
* ***********************************************************/
SortedDictionary<string, string> objLookupResults = new SortedDictionary<string, string>();
// --- note how I added /text()... doesn't change much, but being specific <<<<<<
var kschlResultList = docresult.SelectNodes("//root/CalculationLogCompact/CalculationLogRowCompact/KSCHL/text()");
foreach (System.Xml.XmlText objNextTextNode in kschlResultList) {
// get the actual text from the XML text node
string strNextKSCHL = objNextTextNode.InnerText;
// use it to make the XPath to get the INFO --- see the [KSCHL/text()= ...
string strNextXPath = "//SNW5_Pricing_JKV-Q10_full/PricingProcedure[KSCHL/text()=\"" + strNextKSCHL + "\" and PRICE>0]/INFO/text()";
// and get that INFO text! I use SelectSingleNode here, assuming only one INFO for each KSCHL..... if there can be more than one INFO for each KSCHL, then we'd need another loop here
string strNextINFO = docdata.SelectSingleNode(strNextXPath)?.InnerText; // <<< note I added the ? because now there may be no result with the rule PRICE>0.
// --- then you need to put this result somewhere useful to you.
// I'm not sure what that is, so I'll stick it in the Dictionary object.
if (strNextINFO != null) {
objLookupResults.Add(strNextKSCHL, strNextINFO);
}
}
I've some data (row) of some table in a db temp that I want to copy on another db (not temp !) but with the same tablename that has the same number, type and order of columns !
So my idea was to create a function to avoid to repeat myself :
public int copyDB(string **tableName**, int[] **id**)
{
for(int i = 0; i < **id**.Count(); i++)
{
var temp = from t in dbtemp.+(**tableName**)+ where t.student_id == **id**[i]);
}
(...)
}
Is it possible to write i function like this? I will just need to call the function where i want to with the correct args.
I'm still looking also how to copy data, I've found some interesting link like this. I still need to try them.
Thanks for your help
Let's look at this code:
IList<IHouseAnnouncement> list = new List<IHouseAnnouncement>();
var table = adapter.GetData(); //get data from repository object -> DataTable
if (table.Rows.Count >= 1)
{
for (int i = 0; i < table.Rows.Count; i++)
{
var anno = new HouseAnnouncement();
anno.Area = float.Parse(table.Rows[i][table.areaColumn].ToString());
anno.City = table.Rows[i][table.cityColumn].ToString();
list.Add(anno);
}
}
return list;
Is it better way to write this in less code and better fashion (must be :-) )? Maybe using lambda (but let me know how)?
Thanks in advance!
Just FYI, you're never adding the new HouseAnnouncement to your list, and your loop will never execute for the last row, but I'm assuming those are errors in the example rather than in your actual code.
You could do something like this:
return adapter.GetData().Rows.Cast<DataRow>().Select(row =>
new HouseAnnouncement()
{
Area = Convert.ToSingle(row["powierzchnia"]),
City = (string)row["miasto"],
}).ToList();
I usually go for readability over brevity, but I feel like this is pretty readable.
Note that while you could still cache the DataTable and use table.powierzchniaColumn in the lambda, I eliminated that so that you didn't use a closure that wasn't really necessary (closures introduce substantial complexity to the internal implementation of the lambda, so I avoid them if possible).
If it's important to you to keep the column references as they are, then you can do it like this:
using (var table = adapter.GetData())
{
return table.Rows.Cast<DataRow>().Select(row =>
new HouseAnnouncement()
{
Area = Convert.ToSingle(row[table.powierzchniaColumn]),
City = (string)row[table.miastoColumn],
}).ToList();
}
This will add complexity to the actual IL that the compiler generates, but should do the trick for you.
You could do something like this in Linq:
var table = adapter.GetData();
var q = from row in table.Rows.Cast<DataRow>()
select new HouseAnnouncement()
{ Area = float.Parse(row[table.areaColumn].ToString()),
City = row[table.cityColumn].ToString()
};
return q.ToList();
Your "if statement" is not necessary. Your "for loop" already takes care of that case.
Also, your "for loop" will not execute when the number of your Table Rows is 1. This seems like a mistake, and not by design, but I could be wrong. If you want to fix this, just take out the "-1":
for (int i = 0; i < table.Rows.Count; i++)
Well, for one thing, you appear to have an off-by-one error:
for (int i = 0; i < table.Rows.Count - 1; i++)
{
}
If your table has three rows, this will run while i is less than 3 - 1, or 2, which means it'll run for rows 0 and 1 but not for row 2. This may not be what you intend.
Can't go much simpler that one for-loop and no if-statements:
var table = adapter.GetData(); //get data from repository object -> DataTable
IList<IHouseAnnouncement> list = new List<IHouseAnnouncement>(table.Rows.Count);
for (int i = 0; i < list.Length; i++)
{
list[i] = new HouseAnnouncement();
list[i].Area = float.Parse(table.Rows[i][table.areaColumn].ToString());
list[i].City = table.Rows[i][table.cityColumn].ToString();
}
return list;
It takes more characters than linq-version, but is parsed faster by programmer's brain. :)
Readability is, to me, preferable to being succinct with your code--as long as performance is not a victim. Also, I am sure that anyone who later has to maintain the code will appreciate it as well.
Even when I am maintaining my own code, I don't want to look at it, say a couple of months later, and think "what the hell was I trying to accomplish"
I might do something like this:
var table = adapter.GetData(); //get data from repository object -> DataTable
return table.Rows.Take(table.Rows.Count-1).Select(row => new HouseAnnouncement() {
Area = float.Parse(row[table.powierzchniaColumn].ToString()),
City = row[table.miastoColumn].ToString()
}).ToList();
I am reading my DataTable as follow:
foreach ( DataRow o_DataRow in vco_DataTable.Rows )
{
//Insert More Here
}
It crash; because I insert more records.
How can I read my DataTable without reading the new records? Can I read by RowState?
Thanks
Since I don't know what language you are using I can only give general advice.
In most (all?) languages it's not possible to do a foreach over a collection if you are modifying the collection. There are two common ways to deal with this.
Wild ass guessing pseudo code follows:
// first way uses array notation (if possible)
var no_of_rows = vco_DataTable.Rows.count();
for(var i = 0; i < no_of_rows; i++) {
DataRow o_DataRow = vco_DataTable.Rows[i];
//Insert More Here
}
// The second way copies the data
var my_copy = vco_DataTable.Copy()
foreach ( DataRow o_DataRow in my_copy.Rows )
{
//Insert More into vco_DataTable Here
}
copy.Dispose() // delete/destroy the copy
I have long tables generated by datagrid control that go beyond the page width. I would like to convert that into separate table for each row or definition list where each field name is followed by field value.
How would I do that.
Uses jquery. If you have more than one table you'll need to change it to accommodate that. Also, just appends to the end of the document. If you want it elsewhere, find the element you want to place it after and insert it into the DOM at that point.
$(document).ready(
function() {
var headers = $('tr:first').children();
$('tr:not(:first)').each(
function(i,row) {
var cols = jQuery(row).children();
var dl = jQuery('<dl></dl>');
for (var i=0, len = headers.length; i < len; ++i) {
var dt = jQuery('<dt>');
dt.text( jQuery(headers[i]).text() );
var dd = jQuery('<dd>');
dd.text( jQuery(cols[i]).text() );
dl.append(dt).append(dd);
}
$('body').append(dl);
}
);
$('table').remove();
}
);
Here's a reference:
http://www.mail-archive.com/flexcoders#yahoogroups.com/msg15534.html
The google terms I think you want are "invert datagrid". You'll get lots of hits.