AAB40 Ответов: 4

Как изменить внутренний текст из жестко закодированного XML-файла?


Привет,

Правка-перефразирование моего вопроса и изменение кода

Я хотел бы изменить некоторый внутренний текст из моих xml-файлов, жестко закодировав его. Но я натыкаюсь на сообщение об ошибке, в котором говорится, что в коде есть нечитаемые символы. Ошибка возникает в строке XmlDocument.
Я также попытался добавить XmlTextReader для чтения выбранного XML-файла, как я думал, после того, как он был показан в richTextbox, память больше не заполняется содержимым. Таким образом, кнопка btnMakeNegative обычно не знает, что сделать отрицательным. Поэтому нам нужно прочитать то, что находится в richtextbox. Но даже там я получаю сообщение об ошибке, что были найдены странные символы.

Важнейшая цель:
Нажмите кнопку 1, чтобы загрузить Xml-файл из каталога X, и выберите его из списка.
Покажите это в richTextBox
Нажмите на вторую кнопку, чтобы изменить внутренний текст на определенных узлах
нажмите на третью кнопку, чтобы сохранить изменения в определенном каталоге и дать ему исходное имя + "- NEG".

Заранее спасибо.

EDIT 2-нашел причину ошибки, но не знаю, как с ней справиться.

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?


Что я уже пробовал:

Xml-файл выглядит следующим образом (он частичный, но узлы одинаковы во всем документе: root-parentnode -childnode (- subchildnode) с атрибутами или без них:
<?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>


Код есть как таковой:
    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);
            }
        }

Richard Deeming

Репост
Вы уже опубликовали этот вопрос:
https://www.codeproject.com/Questions/1170972/An-unhandled-exception-of-type-system-argumentexce[^]

Karthik_Mahalingam

Не перепечатывайте, вместо этого вы должны обновить существующий вопрос с помощью Улучшить вопрос

AAB40

вот что я здесь сделал! Именно по поручению Ричарда я хотел закрыть этот вопрос и начать все сначала.

Ramza360

Ваши изменения не отражают того, что я опубликовал в своем решении. Вы создаете экземпляр XmlTextReader, но никогда не используете его, просто используйте LoadXml XmlDocument после удаления недопустимых символов.

4 Ответов

Рейтинг:
6

AAB40

Поэтому, прочитав объяснение Ричарда Диминга, я понял, что мне не разрешено изменять объект в строке для использования в качестве строкового Xml и иметь XmlTextReader и XmlDocument в моем коде, чтобы код работал. Вместо этого я просто должен указать на объект (здесь richtTextBox) в виде текста;
Поэтому я решил использовать XmlDocument для продолжения работы,и теперь я прохожу через него.

спасибо тебе, Ричард, за ясное объяснение! (спотыкаясь о Следующий вопрос, но этот уже решен)

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


Рейтинг:
33

Richard Deeming

Проблема обратной косой черты заключается просто в том, что вы смотрите на строку в отладчике. Он показывает строку так, как вам нужно было бы ввести ее в свой код C#; обратные косые черты на самом деле не присутствуют в строке, и \n символы на самом деле являются символами новой строки (Код ASCII 10).

Вы получаете ошибку от new XmlTextReader(_input) для точно по той же причине что вы получаете ошибку от doc.Load(_input) - оба метода предполагают путь к XML-файлу, но вы проходите мимо строка XML-данных.

Как вам сказали вчера, вам нужно изменить свой код, чтобы использовать doc.LoadXml(_input), или передать StringReader к XmlTextReader конструктор.

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);
    }
    
    ...
}


Рейтинг:
2

Ramza360

Вы можете читать xml-строки с помощью XmlDocument, но вы должны использовать LoadXml(selectedFile).

Кроме того, если ваше поле форматированного текста не содержит начальный тег xml, вы должны вставить его в начало текста.

В дополнение к этому, ваш цикл должен проверить ParentNode и атрибуты на 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
            }
        }


AAB40

Привет, Рамза, 1) Да, мой начальный текст в richtTextBox точно такой же, как xml-файл. 2) я уже пытался изменить "doc.Load" на "doc.LoadXml", но у меня все еще есть ошибка дальше. 3) где я могу получить "вход", который вы предлагаете? по-видимому, если я использую
строка selectedFile = richTextBox1. Text;
он не будет генерироваться правильно и выдаст мне первую ошибку. Так что же вы имеете в виду под вводом, пожалуйста?

Ramza360

Да, "вход", о котором я говорил, был ваш richTextBox1.Text. Тем не менее, если он не терпит неудачу в этой строке, то текст отформатирован правильно, это просто вопрос поиска того, что вам нужно.

У тебя есть док.Метод selectsinglenode звонки, которые не существуют, а потом делать .Внутренний текст на нулевом узле вызывает ошибку.

Ramza360

Более того, звоню Доку.SelectSingleNode будет искать узел на верхнем уровне и не будет углубляться в узлы xml. Вам нужно либо посмотреть на дочерние узлы xNode для них (или для добавления к ним), проверить наличие null, а затем что-то сделать со значениями, либо использовать xPath. Я обновлю свое решение.

AAB40

Рамза, я еще не опубликовал весь xmlfile! это просто часть, так как она слишком длинная, чтобы ее публиковать. SelectSingleNodes действительно существуют! но ваш "ввод" ничего не изменит, так как он все равно будет строкой моего richtextbox. Изменение имени переменной не изменит ошибку. это все еще дает мне ошибку "незаконные символы в пути".

Ramza360

Вход был примером, я изменю его на вашу переменную, чтобы остановить путаницу. Однако что касается недопустимых символов в path, то это означает, что в XML-тексте есть символы, которые недопустимы для XML. В этом случае может быть разумно проверить наличие незаконных символов (удалить их или заменить).

Ramza360

Добавлен цикл для проверки недопустимых символов, чтобы, по крайней мере, начать их поиск. Вы можете изменить его так, чтобы недействительные символы автоматически заменялись, что, вероятно, быстрее, чем выслеживать их самостоятельно.

Ramza360

Там я просто добавил кусок кода, который удалит незаконные символы, если этого недостаточно или вам нужен какой-то другой символ вместо них, измените цикл, чтобы добавить этот символ, когда он не является допустимым xml-символом.

AAB40

xml-файл создается по схеме W3school. так что никаких странных персонажей в нем нет! единственное, что xml-файл начинается с " <?xml version="1.0"? " и что некоторые дочерние теги имеют атрибуты. Это все.

AAB40

ваше решение все еще не работает. Все еще есть проблема с XmlTextReader, который видит странные символы. я не понимаю. Может быть, мне нужно что-то добавить к ссылкам или использовать системы?

AAB40

Рамза, спасибо, что уделил мне время, но я понял, откуда взялась эта проблема. Так что теперь возникает еще одна проблема. Я отредактировал описание. Не могли бы вы взглянуть?

Ramza360

Я только что удалил цикл, собирающий недопустимые символы, так что это вас не смущает, однако вы все еще пытаетесь загрузить текст с помощью .Load, а не с помощью XmlTextReader вообще. Кроме того, если вы используете мой код для удаления символов invaluid, вам нужно использовать строку из StringBuilder в качестве параметра LoadXml...

Рейтинг:
0

Richard MacCutchan

Это точно такая же проблема, как и Необработанное исключение типа "system. argumentexception" произошло в mscorlib.dll дополнительная информация: незаконные символы в пути.[^]. Вы читаете XML-текст в элемент управления RichEdit, а затем пытаетесь использовать этот текст в качестве имени файла для хранения обновленного текста. Вам нужно использовать то же имя файла, из которого вы первоначально читали данные, или, еще лучше, новое имя файла, чтобы не перезаписывать оригинал.


AAB40

Ошибка исключения вызвана недопустимой инструкцией обработки. Например, инструкция обработки может содержать посторонние пробелы. Ниже приведен пример недопустимой инструкции обработки:
<? xml version= '1.0'? & gt; Ref. https://support.microsoft.com/en-us/help/307548/how-to-read-xml-from-a-file-by-using-visual-c. Так что на самом деле я думаю, что это хорошая идея-зацикливаться на недопустимых символах. И да, я добавил оригинальный код, чтобы показать проблему.

AAB40

Ричард, я поместил на нем другое название, чтобы не путать умы читателей. Мой вопрос все еще остается!!!: как я могу прочитать содержимое XML-файла, который был пневмомеханический способ В управления richtextbox? Потому что именно на эту проблему мы и наткнулись, и именно об этом вы не могли мне рассказать. Конечно, мне нужно поставить оригинальный вопрос под рукой, иначе тот, кто читает это, не поймет или даст мне ложное решение!.

Richard MacCutchan

"как я могу прочитать содержимое XML-файла, который был открыт в richtextbox?"

Что это значит? Вы уже прочитали XML-файл, иначе его не было бы в RichTextBox.