Click here to Skip to main content
15,870,130 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
See more:
Hi,

EDIT - refrasing my question and changing the code

I would like to change some innertext from my xml files by hardcoding it. But I'm stumbling on an error message that says that there are unreadable characters in the code. The error is thrown on the XmlDocument line.
I've also tried to add an XmlTextReader to read the selected XML file as I thought after it has been showed in the richTextbox, the memory isn't filled anymore with the content. So the button btnMakeNegative normally doesn't know what to make negative. Therefore we need to read out what's IN the richtextbox. But even there I'm getting the errormessage that strange characters were found.

Major purpose:
Click on button 1 to load an Xml file from directory X and choose the file out of a list.
Show this in a richTextBox
Click on a second button to change inner text on particular nodes
click on a third button to save the changes in a particular directory and give it the original name + "- NEG".

Thanks in advance.

EDIT 2 - Found the reason of the error but don't know how to handle it.

ok, I have found over which weird characters the code is stumbling but I can't fix it. Apparently, the xml file that I've opened with my button_click is read as a kind of HTML instead of an xml file. After initiating the XmlReader the reader can't figure out the backslashes and the backslashes+n in the file. when reading it it looks like this:

Hide   Copy Code
"<?xml version=\"1.0\"?>\n<PrepaymentGridfeeDataByServiceDeliveryPoint xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns=\"un:unece:260:data:EEM:02-02-PrepaymentGridfeeDataByServiceDeliveryPoint\">\n  <HeaderBEEnergyDocument>\n    <Identification>45071dc8-558d-439a-8f0a-88ae73a74910</Identification>\n    <DocumentType listAgencyIdentifier=\"6\">386</DocumentType>\n    <Creation>2016-06-14T12:31:58.0+01:00</Creation>\n    <SenderBEEnergyParty>\n      <Identification schemeAgencyIdentifier=\"9\">5414488009809</Identification>\n    </SenderBEEnergyParty>\n    <RecipientBEEnergyParty>\n      <Identification schemeAgencyIdentifier=\"9\">0000000000000</Identification>  \n    </RecipientBEEnergyParty>\n    <IssuerBEEnergyParty>\n      <Identification schemeAgencyIdentifier=\"9\">5414488009809</Identification>\n    </

Notice the backslashes? They should be in the opposite way for an xml. And why the hell are there spaces in this file? Really weird!

So a solution would be that when I open openFileDialog1 I find a way to make him read the text in XML and not in PlainText. Is there a way to do this? Or should I need to give up the openFileDialog toolbox for this issue? what to use instead then?


What I have tried:

Xml file looks like this (it's partial but the nodes are the same in the whole document: root - parentnode -childnode (- subchildnode) with or without attributes:
<?xml version="1.0"?>
<AnXMLTestFile xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="un:unece:260:data:EEM:AnXMLTestFile">
  <HeaderBEDocument>
    <Identification>45071dc8-558d-439a-8f0a-88ae73a74910</Identification>
    <DocumentType listAgencyIdentifier="6">386</DocumentType>
    <Creation>2016-06-14T12:31:58.0+01:00</Creation>
    <SenderBEParty>
      <Identification schemeAgencyIdentifier="9">1234567890123</Identification>
    </SenderBEParty>
    <RecipientBEParty>
      <Identification schemeAgencyIdentifier="9">1234567890123</Identification>  
    </RecipientBEParty>
    <IssuerBEParty>
      <Identification schemeAgencyIdentifier="9">1234567890123</Identification>
    </IssuerBEParty>
    <AddresseeBEParty>
      <Identification schemeAgencyIdentifier="9">1234567890123</Identification>
    </AddresseeBEParty>
    <DocumentStructureRevision>02-02.001</DocumentStructureRevision>
  </HeaderBEDocument>
</AnXMLTestFile>


Code is as such:
    public partial class frmEditXML : Form
    {
        //get files from directory
        string[] path = Directory.GetFiles(@"C:\Users\decraiec\Documents\A_Automated", "*.XML");

        public frmEditXML()
        {
            InitializeComponent();
        }

        private void btnSelectFile_Click(object sender, EventArgs e)
        {
            openFileDialog1.Filter = "xml files|*.xml|All files|*.*";
            if (openFileDialog1.ShowDialog() == DialogResult.OK)
            {
                try
                {
                    richTextBox1.LoadFile(openFileDialog1.FileName, RichTextBoxStreamType.PlainText);
                }
                catch (Exception exc)
                {
                    MessageBox.Show("An error occured: " + System.Environment.NewLine + exc.ToString() + System.Environment.NewLine);
                    throw;
                }
            }
        }

        private void btnMakeNegative_Click(object sender, EventArgs e)
        {
<pre> //Read selected file. For this create a reader.
            string _input = richTextBox1.Text;
            // You can pre-check the entire text by checking each character.
            // Though not totally efficient it does work.
            List<string> invalidChars = new List<string>();

            // You can change the loop to be able to replace the invalid characters if you like. This is an exampled to see what characters are bad.
            foreach (char ch in _input)
            {
                if (!XmlConvert.IsXmlChar(ch))
                {
                    invalidChars.Add(ch.ToString());
                }
            }
            XmlReaderSettings settings = new XmlReaderSettings();
            settings.IgnoreWhitespace = true;
            XmlTextReader reader = new XmlTextReader(_input); /*always error message*/
            XmlDocument doc = new XmlDocument();
            doc.Load(_input);
            XmlNodeList nodeList = doc.DocumentElement.SelectNodes("/AnXMLTestFile/");
            //find the node to change the content
            //if node is not present, do nothing
            foreach (XmlNode xNode in doc)
            {
                if (xNode.ParentNode.Attributes["HeaderBEDocument"].Value != "")
                {
                    doc.SelectSingleNode("Identification").InnerText = "string";
                    doc.SelectSingleNode("SCI").InnerText = "string";
                    doc.SelectSingleNode("ReferenceType").InnerText = "string";
                    doc.SelectSingleNode("CCType").InnerText = "AA";
                }
                else { } //do nothing
            }
        }

        private void btnSavechanges_Click(object sender, EventArgs e)
        {
            if (saveFileDialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                File.WriteAllText(saveFileDialog1.FileName, richTextBox1.Text);
            }
        }
Posted
Updated 19-Feb-17 23:05pm
v9
Comments
Karthik_Mahalingam 17-Feb-17 8:23am    
Dont Repost, instead you shall update the existing question using Improve question
AAB40 17-Feb-17 8:26am    
that's what I have done here! It was on behalve of Richard that I wanted the other question closed and start over again here.
Ramza360 17-Feb-17 10:21am    
Your changes do not reflect what i've posted in my solution. You are instantiating an XmlTextReader but never use it, just use XmlDocument's LoadXml after you remove the invalid characters.

The backslash issue is simply that you are looking at the string in the debugger. It shows the string as you would need to type it in your C# code; the backslashes are not actually present in the string, and the \n characters are actually newline characters (ASCII code 10).

You're getting an error from new XmlTextReader(_input) for exactly the same reason that you're getting an error from doc.Load(_input) - both methods expect the path to an XML file, but you are passing in a string of XML data.

As you were told yesterday, you need to change your code to use the doc.LoadXml(_input), or pass a StringReader to the XmlTextReader constructor.
C#
private void btnMakeNegative_Click(object sender, EventArgs e)
{
    var doc = new XmlDocument();
    
    // Either:
    doc.LoadXml(richTextBox1.Text);
    
    // or:
    using (var input = new StringReader(richTextBox1.Text))
    using (var reader = XmlReader.Create(input))
    {
        doc.Load(reader);
    }
    
    ...
}
 
Share this answer
 
You can read xml strings with XmlDocument but you must use LoadXml(selectedFile).

Also if your rich text box does not include the xml beginning tag, you must insert that to the beginning of the text.

In addition to that, your loop should check ParentNode and Attributes for null.


C#
private void btnMakeNegative_Click(object sender, EventArgs e)
        {
            //Read selected file
            string selectedFile = richTextBox1.Text;//==>this was the reason of the error message
            XmlDocument doc = new XmlDocument();
            

            // Or just use the below code to remove them.
            StringBuilder newString = new StringBuilder();
            char ch;
        
            for (int i = 0; i < selectedFile.Length; i++)
            {
        
                ch = selectedFile[i];              
                if (XmlConvert.IsXmlChar(ch)) {
                    newString.Append(ch);
                }
            }

            selectedFile = newString.ToString();

            // The below change will build the XmlNode tree
            // An error will occur still if the xml is not formatted correctly.
            doc.LoadXml(selectedFile);


            //find the node to change the content
            //if node is not present, do nothing
            foreach (XmlNode xNode in doc)
            {            
                // change values
            }
        }
 
Share this answer
 
v7
Comments
AAB40 16-Feb-17 10:51am    
Hello Ramza, 1) yes my beginning text in the richtTextBox is just like the xml file. 2) I already have tried to change "doc.Load" into "doc.LoadXml" but I'm still having an error further away. 3) where do I get the "input" that you're suggestingf? apparently if I use
string selectedFile = richTextBox1.Text;
it won't generate correctly and give me the first error. So what do you mean with input please?
Ramza360 16-Feb-17 10:56am    
Yes the 'input' i was referring to was you richTextBox1.Text. That said, if it does not fail on that line then the text is formatted correctly, its just a matter of looking for what you need.

You have doc.SelectSingleNode calls that do not exist, and then doing a .InnerText on a null node causes error.
Ramza360 16-Feb-17 10:58am    
Furthermore, calling doc.SelectSingleNode will look for the node at the top level and not go any deeper into the xml nodes. You need either look at the child nodes of the xNode for them (or for adding to), check for null then do something with the values, or use xPath. I will update my solution.
AAB40 16-Feb-17 11:01am    
Ramza, I don't have published the whole xmlfile! it's just a part as it is too long to post. the SelectSingleNodes DO exist! ;-). but your 'input' will not change anything as it still will be the string of my richtextbox. Changing my variable name will not change the error. it still gives me the 'Illegal characters in path.' error
Ramza360 16-Feb-17 11:04am    
The input was an example, I will change it to your variable to stop the confusion. However about the illegal characters in path, that means there are characters in the XML text that are not valid for XML. In that case it may be prudent to check for illegal characters (removing them or replacing them).
This is exactly the same issue as An unhandled exception of type 'system.argumentexception' occurred in mscorlib.dll additional information: illegal characters in path.[^]. You are reading XML text into a RichEdit control, and later trying to use that text as a file name to store the updated text. You need to use the same filename as you originally read the data from, or better still, a new filename in order not to overwrite the original.
 
Share this answer
 
Comments
AAB40 17-Feb-17 5:18am    
The exception error is caused by an invalid processing instruction. For example, the processing instruction may contain extraneous spaces. The following is an example of an invalid processing instruction:
<?xml version='1.0' ?> Ref. https://support.microsoft.com/en-us/help/307548/how-to-read-xml-from-a-file-by-using-visual-c. So actually I think it's a good idea to loop against invalid chars. And yes, I added the original code to show the issue.
AAB40 17-Feb-17 6:20am    
richard, I have put another title on it not to mix up the minds of the readers. My question still remains!!!: how can I read the content of an XML file that was openend in a richtextbox? Because THAT is the issue we've stumbled on and the thing you couldn't tell me. Of course I need to put the original issue at hand otherwise the one reading this will not understand or give me a false solution!.
Richard MacCutchan 17-Feb-17 6:48am    
"how can I read the content of an XML file that was openend in a richtextbox?"

What does that mean? You have already read the XML file, otherwise it would not be in the RichTextBox.
So after reading the explanation from richard Deeming I've understood that I'm not allowed to change the object in a string to use as a string Xml and to have an XmlTextReader AND an XmlDocument in my code for the code to work. Instead I just have to point to the object (here a richtTextBox) as a text;
So I have decided to use XmlDocument to go on with and now I'm passing through.

thank you richard for the clear explanation! (stumbling on next issue but this one is solved)

private void btnMakeNegative_Click(object sender, EventArgs e)
  {

      //Read selected file.
      XmlDocument doc = new XmlDocument();
      doc.LoadXml(richTextBox1.Text);  //<--
      XmlNodeList nodeList = doc.DocumentElement.SelectNodes("/AnXMLTestFile/");
      //find the node to change the content
      //if node is not present, do nothing
      foreach (XmlNode xNode in doc)
      {
          if (xNode.ParentNode.Attributes["HeaderBEDocument"].Value != "")
          {
              doc.SelectSingleNode("Identification").InnerText = "string";
              doc.SelectSingleNode("SCI").InnerText = "string";
              doc.SelectSingleNode("ReferenceType").InnerText = "string";
              doc.SelectSingleNode("CCType").InnerText = "AA";
          }
          else { } //do nothing
      }
  }
 
Share this answer
 
v3

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900