2011-08-15 5 views
0

xml 파일을 열고 편집 한 다음 저장할 수있는 프로그램이 있습니다. 문제는 설정 파일 (.exe.config)을 열면 저장과 덮어 쓰기가 제대로되지만 전체 파일의 형식이 손실되어 하나의 거대한 한 줄로됩니다. 물론 내 프로그램으로 사용자는 그것이 한 줄이라는 것을 결코 보지 않을 것이므로 내 프로그램의 기능상의 주요한 문제는 아니지만 그 누구나 구성 XML 파일의 형식을 그대로 유지하는 방법을 알고 있습니까? 열 때 설정 값을 변경하는 것뿐입니다. 나는 나의 지식에 대한 형식/들여 쓰기에 아무 것도하지 않았다. 아니면 왜 이런 일을하는지에 대한 통찰력을 가지고 있습니까?xml 구성 파일을 수정하면 한 줄의 파일이됩니다.

감사합니다. Tf.rz

편집

: 여기 코드입니다 :

using System; 
using System.Collections.Generic; 
using System.Collections.Specialized; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Linq; 
using System.Text; 
using System.IO; 
using System.Windows.Forms; 
using System.Configuration; 
using System.Xml; 

namespace WindowsFormsApplication4 
{ 
    public partial class ProgramConfig : Form 
    { 
     public ProgramConfig() 
     { 
      InitializeComponent(); 
     } 

     private XmlDocument m_XmlDoc; 

     private FileStream fIn; 
     private StreamReader sr; 
     private StreamWriter sw; 

     private OrderedDictionary m_Settings; 

     private int m_savecounter = 0; 

     private void ProgramConfig_Load(object sender, EventArgs e) 
     { 
      try 
      { 
       textBox1.Text = "File open: " + GatewayConfiguration.Properties.Settings.Default.Config; 
       int index = 0; 
       loadconfigfile(GatewayConfiguration.Properties.Settings.Default.Config); 
       string[] keys = new string[m_Settings.Keys.Count]; 
       m_Settings.Keys.CopyTo(keys, 0); 
       string[] values = new string[m_Settings.Values.Count]; 
       m_Settings.Values.CopyTo(values, 0); 

       BindingList<KeyValueType> list = new BindingList<KeyValueType>(); 
       for (index = 0; index < m_Settings.Count; index++) 
       { 
        list.Add(new KeyValueType(keys[index], values[index].ToString())); 
       } 
       dataGridView1.Columns.Add(new DataGridViewTextBoxColumn()); 
       dataGridView1.Columns.Add(new DataGridViewTextBoxColumn()); 
       dataGridView1.Columns[0].Name = "Key"; 
       dataGridView1.Columns[0].DataPropertyName = "key"; 
       dataGridView1.Columns[1].Name = "Value"; 
       dataGridView1.Columns[1].DataPropertyName = "value"; 

       var source = new BindingSource(); 
       source.DataSource = list; 
       dataGridView1.DataSource = source; 
       for (index = 0; index < dataGridView1.Columns.Count; index++) 
       { 
        // Auto resize while keeping user resize true. 
        dataGridView1.Columns[index].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells; 
        int initialAutoSizeWidth = dataGridView1.Columns[index].Width; 
        dataGridView1.Columns[index].AutoSizeMode = DataGridViewAutoSizeColumnMode.NotSet; 
        dataGridView1.Columns[index].Width = initialAutoSizeWidth; 
       } 
       dataGridView1.ReadOnly = false; 
       dataGridView1.Columns.Add(new DataGridViewTextBoxColumn()); 
       dataGridView1.Columns[2].Name = "New Value"; 
      } 
      catch (Exception ex) 
      { 
       textBox1.Text = ex.Message; 
      } 
     } 

     private void loadAppSettings() 
     { 
      m_Settings = new OrderedDictionary(); 
      XmlNodeList nl = m_XmlDoc.GetElementsByTagName("setting"); 
      foreach (XmlNode node in nl) 
      { 
       try 
       { 
        m_Settings.Add(node.Attributes["name"].Value, node.ChildNodes[0].InnerText); 
       } 
       catch (Exception) 
       { 
       } 
      } 
     } 

     public void loadconfigfile(string configfile) 
     { 
      if (File.Exists(configfile)) 
      { 
       m_XmlDoc = new XmlDocument(); 
       GatewayConfiguration.Properties.Settings.Default.Config = configfile; 
       GatewayConfiguration.Properties.Settings.Default.Save(); 

       fIn = new FileStream(configfile, FileMode.Open, FileAccess.ReadWrite); 
       sr = new StreamReader(fIn); 
       sw = new StreamWriter(fIn); 
       try 
       { 
        m_XmlDoc.LoadXml(sr.ReadToEnd()); 
        m_XmlDoc.PreserveWhitespace = true; 
        loadAppSettings(); 
       } 
       catch (Exception ex) 
       { 
        throw ex; 
       } 
      } 
      else 
      { 
       throw new FileNotFoundException(configfile + " does not exist."); 
      } 
     } 

     private void SaveAppSettings_Click(object sender, EventArgs e) 
     { 
      MessageBoxButtons buttons = MessageBoxButtons.YesNo; 
      DialogResult result = MessageBox.Show("Overwrite the old values with the new values?", "Save Settings?", buttons); 
      if (result == DialogResult.No) 
      { 
       return; 
      } 
      int index = 0; 
      string[] keys = new string[m_Settings.Keys.Count]; 
      m_Settings.Keys.CopyTo(keys, 0); 
      for (index = 0; index < dataGridView1.Rows.Count; index++) 
      { 
       if ((string)dataGridView1[2, index].Value != string.Empty) 
       { 
        setAppSetting(keys[index], (string)dataGridView1[2, index].Value); 
       } 
      } 
      textBox1.Text = "Settings Saved. You may now exit."; 
      m_savecounter++; 
      dataGridView1.Update(); 
      dataGridView1.Refresh(); 
     } 

     public void setAppSetting(string name, string newValue) 
     { 
      if (!m_Settings.Contains(name)) 
      { 
       throw new Exception(String.Format("Setting {0} does not exists in {1}", name, GatewayConfiguration.Properties.Settings.Default.Config)); 
      } 
      else 
      { 
       if (newValue == null || m_Settings[name].ToString() == newValue) 
       { 
        return; 
       } 
       m_Settings[name] = newValue; 
       m_XmlDoc.SelectSingleNode("//setting[@name='" + name + "']").ChildNodes[0].InnerXml = newValue; 
       fIn.SetLength(0); 
       sw.Write(m_XmlDoc.InnerXml); 
       sw.Flush(); 
      } 
     } 

     public class KeyValueType 
     { 
      private string _key; 
      public string Key 
      { 
       get 
       { 
        return _key; 
       } 
      } 

      private string _value; 
      public string Value 
      { 
       get 
       { 
        return _value; 
       } 
      } 

      public KeyValueType(string key, string value) 
      { 
       _key = key; 
       _value = value; 
      } 
     } 

     private void ProgramConfig_FormClosing(object sender, FormClosingEventArgs e) 
     { 
      if (m_savecounter == 0) 
      { 
       MessageBoxButtons buttons = MessageBoxButtons.YesNo; 
       DialogResult result = MessageBox.Show("You have not saved, still want to exit?", "Exit?", buttons); 
       if (result == DialogResult.No) 
       { 
        e.Cancel = true; 
       } 
      } 
      sw.Close(); 
      sr.Close(); 
      fIn.Close(); 
     } 
    } 
} 
+2

파일을 저장하는 데 사용하는 코드를 표시해야합니다. –

+2

일부 코드가 없으면 도움이되는 방법이나 XML을 구문 분석하는 데 사용하는 클래스에 대한 참조를 알 수 없습니다. –

+0

@Joe White : 코드가 게시되었습니다. 내 잘못이야! –

답변

1

당신이 true로 PreserveWhitespace 속성을 설정할 수 있습니다 XmlDocument를 사용하는 경우 - 기본값을 false로 설정되어 있지 않은 경우.

XDocument에 해당하는 내용은 Load() 과부하이며 LoadOptions.PreserveWhitespace입니다.

+0

답변 해 주셔서 감사합니다. 나는 그 진술을 어디에 넣어야하는지 궁금했다. xmlDocument를로드 한 직후에 넣어야합니까? –

+0

@ tf.rz : 위의'PreserveWhitespace' 링크는 사용 예제가있는 msdn 페이지를 가리 킵니다. 'm_XmlDoc.LoadXml (sr.ReadToEnd())'그리고'm_XmlDoc.PreserveWhitespace = true; 문서를로드하기 전에 속성을 * 설정하십시오. – BrokenGlass

+0

안녕하세요, 귀하의 제안을 시도하고 불행히도 내 xpath가 엉망입니다. 나는 설정 값이 캐리지 리턴 및 개행 이스케이프 문자에 해당한다고 생각하는 상자라고 생각합니다. 노드를 얻으려면 xpath를 수정해야합니까? 그렇지 않으면 변경할 수있는 다른 것이 있습니까? =) –

관련 문제