|
Can you post fuller code?
Also is the code being called the correct number of times (ie twice) even if the code is only setting from one node?
[Edit]
I ran this scratch code:
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml("<HotelAvail><Rooms><Room><RoomRQId>1</RoomRQId><Quantity>1</Quantity><NumAdults>3</NumAdults></Room><Room><RoomRQId>2</RoomRQId><Quantity>1</Quantity><NumAdults>2</NumAdults></Room></Rooms></HotelAvail>");
XmlNodeList nodeRooms = xmlDoc.SelectNodes("HotelAvail/Rooms/Room");
foreach (XmlNode objRNode in nodeRooms)
{
Console.Write(objRNode["RoomRQId"].InnerText);
Console.Write("\t");
Console.Write(objRNode["Quantity"].InnerText);
Console.Write("\t");
Console.WriteLine(objRNode["NumAdults"].InnerText);
}
Console.ReadKey();
This code outputs as expected:
1 1 3
2 1 2
So it is something else inside the loop causing the problem
CCC solved so far: 2 (including a Hard One!)
37!?!! - Randall, Clerks
modified on Monday, January 11, 2010 6:20 AM
|
|
|
|
|
The entire project is huge and references several classes, so it's impossible to include the whole code, below is a more concise example of what is occuring. Basically for every occurence of the "Room" node, I populate a datatable with the variables, and then write an output. It loops through my for each loop twice, but sets the variables each time to the first occurence only. And therefore I get two nodes output, which are both derived from the first datatable created, and the first set of room child nodes in the xml document. The rest of this project is working 100% perfectly, but this is the only area where I need to loop through a list of nodes, as all other nodes occur once.
XmlNodeList nodeRooms = xmlDoc.SelectNodes("/test:HotelAvail/test:Rooms/test:Room", ns);
foreach (XmlNode objRNode in nodeRooms)
{
intRoomRQId = int.Parse(objRNode["RoomRQId"].InnerText);
strQuantity = objRNode["Quantity"].InnerText;
intNumAdults = int.Parse(objRNode["NumAdults"].InnerText);
DataTable dt = objAvailability.SelectHotelAvail(intRoomRQId, strQuantity, intNumAdults);
if (dt.Rows.Count >0)
{
objWriter.WriteStartElement("Room");
objWriter.WriteStartElement("RoomRQId");
objWriter.WriteString(intRoomRQId.ToString());
objWriter.WriteEndElement(); //RoomRQID
..... other items from datatable are written here
}
}
|
|
|
|
|
Seems to me intRoomRQId is updating as it should, and the bug is inside SelectHotelAvail(), returning the same row over and over for unknown reasons.
|
|
|
|
|
I edited my last post with some scratch code based on yours, it is iterating through correctly. The things that are different (on mine) are:
1. I don't have any namespaces.
2. I had to modify the XML you posted to have a root <HotelAvail> element
The code you have posted just looks like it should work OK to me. A few things to check:
a. I assume you've done this alread, but put a breakpoint at the start of the foreach loop and inspected the nodeRooms list manually, and checked the objNode object at each iteration.
b. I assume intRoomRQId , strQuantity , intNumAdults value types (string, int etc) otherwise there is a danger objAvailability.SelectHotelAvail(intRoomRQId, strQuantity, intNumAdults); will change them.
c. Do you have more than one Rooms node?
Also, how can you tell that only the first set of values are being used (e.g. from, the database table, by breakpoint), related to this, what is objWriter? It is possible that the writer is not wroking correctly.
CCC solved so far: 2 (including a Hard One!)
37!?!! - Randall, Clerks
|
|
|
|
|
Here is a complete XML snapshot:
<?xml version="1.0" encoding="utf-8">;
<HotelAvail xmlns="http://www.transhotel.com/transHotel/2004A"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.transhotel.com/transHotel/2004A HotelAvailRQ.xsd">
<WholesalerID>TRANSHOTEL</WholesalerID>
<Hotels>
<HotelCode>1154718</HotelCode>
</Hotels>
<Dates>
<CheckIn>2010-01-21</CheckIn>
<CheckOut>2010-01-22</CheckOut>
</Dates>
<Rooms>
<Room>
<RoomRQId>1</RoomRQId>
<Quantity>1</Quantity>
<NumAdults>3</NumAdults>
</Room>
<Room>
<RoomRQId>2</RoomRQId>
<Quantity>1</Quantity>
<NumAdults>2</NumAdults>
</Room>
</Rooms>
</HotelAvail>
If I run in debug mode, on the first pass through ForEach it says that the innertext will be 113 (for the whole occurrence of that node), on the second pass it says that the innertext will be 212 (which is correct). So the problem has got to be how the variables are set from the referenced nodes. For some reason it is selecting the 1st occurence of each element within Room even though it is running within a loop. I know this can be a problem with say SelectSingleNode, but I'm not using that. So therefore objRNode["RoomRQId"].InnerText is not iterative, and is always picking the 1st occurence with the document.
A namespace is used and referenced as follows:
XmlNamespaceManager ns = new XmlNamespaceManager(xmlDoc.NameTable);
ns.AddNamespace("test", "http://www.transhotel.com/transHotel/2004A");
There is only one "Rooms" node, so that is selected explicitly so as to ensure no confusion. Objwriter is an XMLTextWriter which is merely writing the output.
|
|
|
|
|
jamesc69 wrote: If I run in debug mode, on the first pass through ForEach it says that the innertext will be 113 (for the whole occurrence of that node), on the second pass it says that the innertext will be 212 (which is correct).
OK, so we've eliminated two possibilities: The xmlDoc.SelectNodes is selecting the node correctly and the loop is iterating over the nodes correctly.
jamesc69 wrote: I know this can be a problem with say SelectSingleNode, but I'm not using that. So therefore objRNode["RoomRQId"].InnerText is not iterative, and is always picking the 1st occurence with the document.
Correct xmlnode["NodeName"].InnerText is not iterative, however you are the source xmlnode (in your case objRNode) is the result of an interation. So you will get the objRNode["RoomRQId"].InnerText will get the InnerText of the current objRNode 's RoomRQId correctly. Both the code I posted earlier shows that to be the case and Luc Pattyn has tested it.
jamesc69 wrote: So therefore objRNode["RoomRQId"].InnerText is not iterative, and is always picking the 1st occurence with the document.
Not necessarily (see above). It is possible that, as Luc said, SelectHotelAvail() is fouling up somehow. It is possible that the output code is not working as expected, or that somehow the value is being set in another place (e.g. later in the code, concurrency problems). Without full source code this is hard to find.
The line intRoomRQId = int.Parse(objRNode["RoomRQId"].InnerText); should get the correct Id. I'd use a breakpoint to ensure that correct ID is being set by that line, then step through to see if it changes.
CCC solved so far: 2 (including a Hard One!)
37!?!! - Randall, Clerks
|
|
|
|
|
keefb wrote: and Luc Pattyn has tested it.
No, you misunderstood. I did not test anything, it just seemed from code+observations that the bug was probably inside the method of which no code was shown at all.
|
|
|
|
|
Apologies, I thought you'd run some code like mine...
CCC solved so far: 2 (including a Hard One!)
37!?!! - Randall, Clerks
|
|
|
|
|
Hi,
First of all thanks all for your help, but this apparently isn't a coding problem, but actually a problem with my Vis Studio. My Vis Studio was not building a new dll each time and therefore any change I was making was having no effect. I created a new solution, added all the existing files into the new solution, and guess what - it now works!
Apologies for wasting everyone's time.
|
|
|
|
|
Glad you got it sorted!
CCC solved so far: 2 (including a Hard One!)
37!?!! - Randall, Clerks
|
|
|
|
|
Is there a reason you're not using linq-to-xml? It's much simpler (types from memory, so you may need to tweak it a bit)...
XDocument doc = XDocument.Load("myfile.xml");
XElement root = doc.Element["Rooms"];
foreach (XElement element in root.Elements)
{
int roomID = Convert.ToInt32(element.Element["RoomRQID"].Value);
int quantity = Convert.ToInt32(element.Element["Quantity"].Value);
int numAdults = Convert.ToInt32(element.Element["NumAdults"].Value);
}
No messing around with InnerText and that kind of crap.
.45 ACP - because shooting twice is just silly ----- "Why don't you tie a kerosene-soaked rag around your ankles so the ants won't climb up and eat your candy ass..." - Dale Earnhardt, 1997 ----- "The staggering layers of obscenity in your statement make it a work of art on so many levels." - J. Jystad, 2001
|
|
|
|
|
I have a regular DataGridView and RowHeadersVisible is set to true. How do I get the location and size of the cell in the upper leftmost corner (the one to the left of the headings)?
|
|
|
|
|
DataGridView[0,0].value!!!!
|
|
|
|
|
Thanks, but I figured it out finally:
DataGridView.GetCellDisplayRectangle(-1, -1, true)
|
|
|
|
|
hw can i append text to end of a file?
|
|
|
|
|
System.IO.File.AppendAllText( string path, string contents )
Nick
----------------------------------
Be excellent to each other
|
|
|
|
|
MSDN link Here[^].
There are only 10 types of people in this world — those who understand binary, and those who don't. |
|
|
|
|
|
Dear all,
I want to create a large .txt file but when i run my code i got a strange thing,
A messagebox say's: "No Symbols are loaded for any call stack frame. The source code cannot be displayed."
and a warning say's "The CLR has been unable to transition from COM context 0x1c2000 to COM context 0x1c2170 for 60 seconds. The thread that owns the destination context/apartment is most likely either doing a non pumping wait or processing a very long running operation without pumping Windows messages. This situation generally has a negative performance impact and may even lead to the application becoming non responsive or memory usage accumulating continually over time. To avoid this problem, all single threaded apartment (STA) threads should use pumping wait primitives (such as CoWaitForMultipleHandles) and routinely pump messages during long running operations."
My code is:
string prev="";<br />
<br />
string connectionString = "Provider=Microsoft.JET.OLEDB.4.0;data source=E:\\ICA_Newspapers.mdb";<br />
<br />
OleDbConnection conn = new OleDbConnection(connectionString);<br />
<br />
string sql = "SELECT * FROM All_Analyzed_Corpus";<br />
<br />
OleDbCommand cmd = new OleDbCommand(sql, conn);<br />
<br />
conn.Open();<br />
<br />
OleDbDataReader reader;<br />
reader = cmd.ExecuteReader();<br />
<br />
StreamWriter tw = new StreamWriter(Application.StartupPath + "\\TaggedCorpus.txt");<br />
<br />
StringBuilder text = new StringBuilder();<br />
<br />
<br />
while (reader.Read())<br />
{<br />
if (reader.GetValue(1).ToString() == "/D")<br />
{<br />
text.Append("</s>");<br />
<br />
tw.WriteLine(text);<br />
tw.Flush();<br />
text = text.Remove(0, text.Length);<br />
<br />
text.Append("<s> ");<br />
prev = "/D";<br />
}<br />
else if (reader.GetValue(1).ToString() == "/T" && prev != "/D")<br />
{<br />
text.Append("</s>");<br />
tw.WriteLine(text);<br />
tw.Flush();<br />
<br />
text = text.Remove(0, text.Length);<br />
<br />
text.Append("<s> ");<br />
prev = "/T";<br />
}<br />
else if (reader.GetValue(1).ToString() == "/P" && prev != "/T")<br />
{<br />
text.Append("</s>");<br />
tw.WriteLine(text);<br />
tw.Flush();<br />
<br />
text = text.Remove(0, text.Length);<br />
<br />
text.Append("<s> ");<br />
prev = "/P";<br />
}<br />
<br />
<br />
<br />
if(reader.GetValue(5).ToString().Contains("/"))<br />
{<br />
pr1 = reader.GetValue(5).ToString().Split(char.Parse("/"))[1];<br />
}<br />
else<br />
{<br />
pr1 = reader.GetValue(5).ToString();<br />
}<br />
<br />
if (reader.GetValue(6).ToString().Contains("/"))<br />
{<br />
pr2 = reader.GetValue(6).ToString().Split(char.Parse("/"))[1];<br />
}<br />
else<br />
{<br />
pr2 = reader.GetValue(6).ToString();<br />
}<br />
<br />
if (reader.GetValue(7).ToString().Contains("/"))<br />
{<br />
pr3 = reader.GetValue(7).ToString().Split(char.Parse("/"))[1];<br />
}<br />
else<br />
{<br />
pr3 = reader.GetValue(7).ToString();<br />
}<br />
if (reader.GetValue(8).ToString().Contains("/"))<br />
{<br />
stm = reader.GetValue(8).ToString().Split(char.Parse("/"))[1];<br />
}<br />
else<br />
{<br />
stm = reader.GetValue(8).ToString();<br />
}<br />
<br />
if (reader.GetValue(9).ToString().Contains("/"))<br />
{<br />
suf1 = reader.GetValue(9).ToString().Split(char.Parse("/"))[1];<br />
}<br />
else<br />
{<br />
suf1 = reader.GetValue(9).ToString();<br />
}<br />
<br />
if (reader.GetValue(10).ToString().Contains("/"))<br />
{<br />
suf2 = reader.GetValue(10).ToString().Split(char.Parse("/"))[1];<br />
}<br />
else<br />
{<br />
suf2 = reader.GetValue(10).ToString();<br />
}<br />
<br />
if (reader.GetValue(14).ToString().Contains("/"))<br />
{<br />
cas = reader.GetValue(14).ToString().Split(char.Parse("/"))[1];<br />
}<br />
else<br />
{<br />
cas = reader.GetValue(14).ToString();<br />
}<br />
<br />
<br />
text.Append(pr1 + "+" + pr2 + "+"<br />
+ pr3 + "+" + stm + "+" + suf1<br />
+ "+" + suf2 + "+" + cas + " ");<br />
<br />
<br />
text = text.Replace(" +", " #+");<br />
text = text.Replace("+++", "+#+#+");<br />
text = text.Replace("++", "+#+");<br />
text = text.Replace("+ ", "+# ");<br />
<br />
<br />
}<br />
<br />
tw.Close();<br />
<br />
reader.Close();<br />
conn.Close();<br />
<br />
Thanks in advance...
|
|
|
|
|
It seems that a COM object needs to respond within 60 seconds, but you create someting in this time.
Is this an operation you run in your main tread (or the thread which created a window)?
I would try to execute Application.DoEvents(); every loop iteration.
Greetings
Covean
|
|
|
|
|
When I did Application.DoEvents(); no message appears but the file size stopped at 7805 kb and the program stopped and thats cant be because the file must end with the last record in my database table.
|
|
|
|
|
Are there no exceptions?
I looked over your code and couldn't find any problem, so I tried if there is maybe a problem with the filesize (I haven't really awaited that there is an error and there is no error. I was able to create an 9GB large text file without problems).
Do you use any other COM-objects in your project?
At next I would try to do this database-"export" in an own thread.
Greetings
Covean
|
|
|
|
|
Hi, in my database I have a bunch of sums which for example can be broken down to (100*25)/3 or whatever the case may be.
How would I work out programatically the sum in the string in my C# app?
Thanks.
Strive to be humble enough to take advice, and confident enough to do something about it.
|
|
|
|
|
Good question. I had thought .NET provided something for doing that sort of thing, but can't find it.
There are a number of projects on the net which provide functionality for doing that sort of thing. Here's one:
http://www.bestcode.com/html/bcparser_net.html
Regards,
Rob Philpott.
|
|
|
|
|
|