views:

572

answers:

6

I wrote a C# Winforms program to take a XML file and load values from a text file into each occurrence of that field which the user specifies on the UI. For whatever reason, the program inserts a carriage return on any nodes which don't contain a value. For example, it will do that to <example></example> whereas it will not misbehave on something like <country>USA</country>

What is causing it to do this and how can I prevent it? Here is the code from the part which handles this functionality.

XmlDocument LoadXmlDoc = new XmlDocument();
StreamReader sr = File.OpenText(DataLoadTxtBx.Text);
string InputFromTxtFile;
LoadXmlDoc.Load(XmlPath.Text);

XmlNodeList NodeToCreateOrReplace = LoadXmlDoc.GetElementsByTagName(XmlTagNameTxtBx.Text);

foreach (XmlNode SelectedNode in NodeToCreateOrReplace)
{
    if ((InputFromTxtFile = sr.ReadLine()) != null)
    {
        SelectedNode.InnerText = InputFromTxtFile;
    }
}
sr.Close();
LoadXmlDoc.Save(XmlPath.Text);
A: 

No exact answer here... Experiment with the XmlDocument.PreserveWhitespace property. Consider using XmlTextWriter for more control (possibly). Also, by the way, wrap your StreamReader in a using block because it is Disposable.

rasx
A: 

Try InputFromTxtFile.Trim() it will get rid of any lingering carriage returns in the text file you are reading in.

Andrew Cox
A: 

Try the following:

SelectedNode.Value = !string.IsNullOrEmpty(InputFromTxtFile = sr.ReadLine()) ? InputFromTxtFile : null;

From what I've see problem occurs when you assign empty string to the InnerText (BTW, why you are using InnerText?)

arbiter
I am looking to replace the existing value every instance of the node which the user defines on the UI. so, i was using the InnerText property to select those values and replace them with values from a text file.
transmogrify
A: 

After doing some testing I have discovered why this behavior was occuring. I was creating objects using the System.xml class. When I parse the XML file, the behavior is that it will apply proper XML formatting to my XML file which is being parsed. In this case, the nodes which do not contain values are being interpreted in an undesired manner.

For example, let's say that I have the following XML document:

<root>

<record_1>
<name>Bob</name>
<employer>Microsoft</employer>
<start_date>September 9, 2009</start_date>
<end_date></end_date>
</record1>

<record_2>
<name>Bill</name>
<employer>Google</employer>
<start_date>November 2, 2004</start_date>
<end_date></end_date>
</record2>

</root>

When the System.xml class is used, it will format the XML and insert a carriage return into the <end_date></end_date> field so it becomes:

<end_date>
</end_date>

This is a problem because the program that I was writing this utility for will not interpret the XML correctly when the carriage return is applied to a field as such which did not previously have that formatting. My solution will be to either find a way to remove the carriage return after the fact or to find another class or set of methods which will not exhibit this behavior.

transmogrify
Its amusing that I get marked down when this is in fact what was occuring in the application.
transmogrify
A: 

From your description it seems that if you are going to put an empty value, it implies that InputFromTxtFile = sr.ReadLine() returned an empty string? Which in turn means an empty line in the text file. If this is so, consider using Regex.Replace(InputFromTxtFile, @"\s", "") as this will replace all forms of white space including: space, tab, linefeed and newline.

Alex K
A: 

I worked with this problem for hours today because BizTalk 2006 R2 interprets

     <XmlElement>
     </XmlElement>

as a carriage return line feed and how many ever spaces for the indentation. I finally discovered a way to use the information rasx provided about preservewhitespace to come up with this solution. An important note is that preservewhitespace does not effect the XmlDocument until either a save or a load action is done on the object. For my example I had a method that received an XmlDocument, manipulated it and then returned it:

public XmlDocument ManipulateIt (XmlDocument inDoc)
{
  //This statement will result in a start and end node with /r/n and spaces in the xmldoc
  inDoc["SomeNode"].InnerText = "";

  //Create a new doc and set the preservewhitespace attribute to true (important to do before calling LoadXml

  XmlDocument rtnDoc = new XmlDocument();
  rtnDoc.PreserveWhitespace = true;

  //When the OuterXml string is loaded into rtnDoc all extra whitespace is removed
  rtnDoc.LoadXml(inDoc.OuterXml);

  return(rtnDoc);
}

By doing it this way when the inDoc is loaded into the rtnDoc all of the extra whitespace is stripped from the xml, leaving you with:

<XmlElement></XmlElement>

I hope this has helped someone else out there working with products that parse XML in different ways. Its a little more annoying when both products are produced by the same company.

(Hopefully I have added enough key words to this post to help the next person find it)

Bill