Click here to Skip to main content
14,329,993 members
Rate this:
Please Sign up or sign in to 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
Richard Deeming 16-Feb-17 12:24pm
   
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.
Rate this:
Please Sign up or sign in to vote.

Solution 4

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.
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);
    }
    
    ...
}
   
Rate this:
Please Sign up or sign in to vote.

Solution 1

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.


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
            }
        }
   
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).
Ramza360 16-Feb-17 11:19am
   
Added a loop to check for invalid characters, to at least get you started in finding them. You can change it so the invalid characters are automatically replaced which is probably faster then hunting them down yourself.
Ramza360 16-Feb-17 11:33am
   
There i just added a piece of code that will remove illegal characters, if that is not sufficient or you need some other character in place of those, change the loop to add that character when not a valid xml char.
AAB40 17-Feb-17 6:18am
   
the xml file is created according W3school scheme. so no strange characters in it! the only thing is that the xml file starts with " <?xml version="1.0"?> " and that some child tags have attributes. That's all.
AAB40 17-Feb-17 6:22am
   
your solution is still not working. Still have an issue with XmlTextReader that sees strange characters. i don't understand. Is there maybe something I need to add to the references or using systems?
AAB40 17-Feb-17 9:54am
   
Ramza, thanks for your time, but I found where the issue came from. So another issue is popping up now. I have edited the describtion. Could you have a look please?
Ramza360 17-Feb-17 10:43am
   
I just removed the loop collecting the invalid characters, so that's not confusing to you, however you are still trying to load the text using .Load, and not using the XmlTextReader at all. Also if you are using my code to remove invaluid characters, you need to use the string from the StringBuilder as the LoadXml parameter...
Rate this:
Please Sign up or sign in to vote.

Solution 2

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.
   
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.
Rate this:
Please Sign up or sign in to vote.

Solution 5

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
      }
  }
   
v3

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




CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100