C#中XML文档的读取编写方法?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C#中XML文档的读取编写方法?相关的知识,希望对你有一定的参考价值。

第一个如何编写XML文档,主要的规则是什么?
第二个XML文档的读取规则?是否和ini配置文件一样?

参考技术A 简单的写操作
XmlWriterSettings settings =new XmlWriterSettings();
settings.Indent=true; //是否支持缩进

XmlWriter writer = XmlWriter.Create("d:\\Products.xml", settings);//xml文件路径
writer.WriteStartDocument();//开始文档 < ?xml version="1.0" encoding="utf-8"?>
writer.WriteComment("xml产品注释.");//注释
writer.WriteStartElement("Product");//开始元素
writer.WriteAttributeString("ID", "001");//元素属性
writer.WriteAttributeString("Name", "Soap");
writer.WriteElementString("Price", "10.00");
writer.WriteStartElement("OtherDetails");//添加子元素
writer.WriteElementString("BrandName", "X Soap");//子元素
writer.WriteElementString("Manufacturer", "X Company");
writer.WriteEndElement();//结束元素
writer.WriteEndDocument();//结束文档

writer.Flush();
writer.Close();

简单的读操作
XmlDocument doc =new XmlDocument();
doc.Load("xml文件路径");
XmlNodeList documents = doc.SelectNodes("Product");//取得product的数目
foreach(XmlNode document in documents)//循环produt

string id = document.Attributes["ID"].Value;
string name = document.Attributes["Name"].Value;
string price = document.ChildNodes[0].InnerText;
string brandName =document.ChildNodes[1].ChildNodes[0].InnerText;


xml和ini 都属于txt类型,但是又有一定的规律。所以读写类似。

使用 C# 使用特殊字符写入 XML 文档

【中文标题】使用 C# 使用特殊字符写入 XML 文档【英文标题】:Write in an XML document with C# using special characters 【发布时间】:2017-05-21 19:21:23 【问题描述】:

我正在尝试在递归函数中使用 XmlWriter 在 C# 中编写 XML 文件。该文件应该包含给定目录中的每个文件夹以及每个子文件夹和文件。

我在尝试在 XML 文件中写入特殊字符时遇到了一些麻烦,它不断地给我一个错误,

我不能使用'&'、'/'、'-'、'.'、''等字符。

偶数不起作用。我尝试找到与此问题类似的问题,但没有解决方案对我有帮助,我尝试替换包含特殊字符的文件夹和/或文件字符串名称,并使用“&”、“"”、“'”转义它们等等,但这也不起作用。它只是给我一个错误,我不能使用'&'。

    using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Xml;

namespace XMLgenerator

    public class Generator
    
        public void write(string Dir, XmlWriter writer)
        
            try
            
                writer.WriteStartElement("Folders");
                 foreach (string s in Directory.GetDirectories(Dir))
              
                    string[] splitter = s.Split('\\');
                    string ss = splitter[splitter.Length - 1];
                    string ssxml = XmlConvert.EncodeLocalName(ss);
                        writer.WriteStartElement("Folder");
                    writer.WriteAttributeString("name", ssxml);

                    foreach (string f in Directory.GetFiles(s))
                    
                        string fxml = XmlConvert.EncodeLocalName(f);
                        FileInfo fi = new FileInfo(f);
                        long length =  fi.Length;
                        writer.WriteElementString(fxml, length.ToString());
                    
                    writer.WriteEndElement();
                    write(s,writer);
                
                writer.WriteEndElement();
            
            catch (UnauthorizedAccessException ex)
            
                Console.WriteLine(ex.Message);
                return;
            
            catch (IOException ex)
            
                Console.WriteLine(ex.Message);
                return;
            
        
        // Method for creating an XML file and also getting directories and files. File name and dir path are parametres
        public void generateContent(string Dir)
            
            XmlWriterSettings xws = new XmlWriterSettings();
            xws.Encoding = new UTF8Encoding();
            using (XmlWriter writer = XmlWriter.Create("test.xml", xws))
            
                writer.WriteStartDocument();
                write(Dir,writer);
                writer.WriteEndDocument();
            

            
        
    

【问题讨论】:

; 之前的空格使转义字符无效。 &amp;amp; 是 '&' 而 &amp;amp ; 是 '&'还有HttpUtility.HtmlEncode and System.Security.SecurityElement.Escape,因此您无需为每个可能的无效字符编码。 嘿,保罗,我刚刚在这个问题中留出了那个空间,因为没有它它会在这里正确翻译,所以它不是 &amp,而是给出了实际的 & 【参考方案1】:

您正试图在 XML 元素名称中包含 '&'、'/'、'-'、'.'、' ' 等等。。其中一些例如“&”根本不能包含在元素名称中,而其他一些例如“-”和数字可以包含——只是不能作为第一个字符。 XML Standard 4th edition(即 currently supported by XmlWriter 版本)定义名称中的有效字符如下:

[4]     NameChar    ::=     Letter | Digit | '.' | '-' | '_' | ':' | CombiningChar | Extender
[5]     Name        ::=     (Letter | '_' | ':') (NameChar)*

在哪里LetterDigit 等。人。定义here。请注意,字母必须在前。

由于您的ss 字符串可能包含无效字符,您可以根据需要使用XmlConvert.EncodeLocalName() 进行转义,然后在读取XML 时使用XmlConvert.DecodeName() 恢复原始字符串。

因此,您的代码如下所示:

    public void write(string Dir, XmlWriter writer)
    
        try
        
            writer.WriteStartElement("Folders");
            foreach (string directoryPath in Directory.GetDirectories(Dir))
            
                string directoryName = Path.GetFileName(directoryPath);
                writer.WriteStartElement(XmlConvert.EncodeLocalName(directoryName));
                foreach (string fileName in Directory.GetFiles(directoryPath))
                
                    FileInfo fi = new FileInfo(fileName);
                    writer.WriteElementString(XmlConvert.EncodeLocalName(fileName), XmlConvert.ToString(fi.Length));
                
                writer.WriteEndElement();
                write(directoryPath, writer);
            
            writer.WriteEndElement();
        
        catch (UnauthorizedAccessException ex)
        
            Console.WriteLine(ex.Message);
            return;
        
        catch (IOException ex)
        
            Console.WriteLine(ex.Message);
            return;
        

但是,我建议使用固定元素名称的替代方法,正如@PaulAbbott 所推荐的那样,它将目录和文件名存储为属性值:

    public void write(string Dir, XmlWriter writer)
    
        try
        
            writer.WriteStartElement("Folders");
            foreach (string directoryPath in Directory.GetDirectories(Dir))
            
                string directoryName = Path.GetFileName(directoryPath);
                writer.WriteStartElement("Folder");
                writer.WriteAttributeString("Name", directoryName);
                foreach (string fileName in Directory.GetFiles(directoryPath))
                
                    FileInfo fi = new FileInfo(fileName);
                    writer.WriteStartElement("File");
                    writer.WriteAttributeString("Name", fileName);
                    writer.WriteValue(fi.Length);
                    writer.WriteEndElement();
                
                write(directoryPath, writer); // I moved this inside the outer <Folder> tag.
                writer.WriteEndElement();
            
            writer.WriteEndElement();
        
        catch (UnauthorizedAccessException ex)
        
            Console.WriteLine(ex.Message);
            return;
        
        catch (IOException ex)
        
            Console.WriteLine(ex.Message);
            return;
        
    

这应该会产生更具可读性的 XML,例如:

<Folders>
  <Folder Name="WpfApplication1">
    <File Name="D:\Temp\Question27864746 XMLapp\WpfApplication1\WpfApplication1.sln">1014</File>
    <File Name="D:\Temp\Question27864746 XMLapp\WpfApplication1\WpfApplication1.v12.suo">84992</File>
    <Folders>
      <Folder Name="WpfApplication1">
        <File Name="D:\Temp\Question27864746 XMLapp\WpfApplication1\WpfApplication1\App.config">187</File>
        <File Name="D:\Temp\Question27864746 XMLapp\WpfApplication1\WpfApplication1\App.xaml">326</File>
      </Folder>
    </Folders>
  </Folder>
</Folders>

【讨论】:

我什至没有意识到他正在用文件夹名称创建元素名称。这是一个非常糟糕的主意,因为您不可能为它编写 XSD。像&lt;folders&gt;&lt;folder name="asdf"&gt;... 这样的东西会比&lt;folders&gt;&lt;asdf&gt;... 好很多,并且可以避免文件夹名称以数字开头的问题。 @PaulAbbott - 同意。 嘿,非常感谢你们,我接受了你们的建议,一切都很好。能否请教一下如何让元素和元素串形成一棵树一样的形状? @LukaZdravkovic - 我的更新回答了你的问题吗?【参考方案2】:

不要尝试修复您的 xml,而是使用 Linq2Xml 来实现类似的事情。

我会这样做(没有字符串处理,没有特殊的字符处理)

XElement Dir2Xml(string dir)

    var dInfo = new DirectoryInfo(dir);
    var files = new XElement("files");

    foreach(var f in dInfo.GetFiles())
    
        files.Add(new XElement("file", f.FullName)); //or use "f.Name" whichever you like
    

    foreach (var d in dInfo.GetDirectories())
    
        files.Add(new XElement("directory", new XAttribute("name", d.Name), Dir2Xml(d.FullName)));
    

    return files;


var xmlstring = Dir2Xml(@"c:\temp").ToString();

【讨论】:

以上是关于C#中XML文档的读取编写方法?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 C# 中读取 XML 文档 [重复]

使用C#进行XML文档读取

如何使用 C# 通过读取另一个 XML 文件来创建 XML 文档?

用C#创建XML文档和读取并修改XML文档

用C#创建XML文档和读取并修改XML文档

使用 C# 在 XML 文件中转换 CSV