Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/319.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用特殊字符用C#编写XML文档_C#_Xml - Fatal编程技术网

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

使用特殊字符用C#编写XML文档,c#,xml,C#,Xml,我试图在递归函数中使用XmlWriter用C#编写一个XML文件。该文件应该包含给定目录中的每个文件夹以及每个子文件夹和文件 我在尝试在XML文件中写入特殊字符时遇到了一些麻烦,它不断地给我带来错误 我不能使用诸如“&”、“/”、“-”、“.”、“.”等字符 甚至连数字都不起作用。我试图找到与此问题类似的问题,但没有任何解决方案对我有所帮助。我尝试替换由特殊字符组成的文件夹和/或文件字符串名称,并使用“&;”、“";”、“'”等对其进行转义。但这也不起作用。它只是给了我一

我试图在递归函数中使用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();
            }

            }
        }
    }

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

[4]     NameChar    ::=     Letter | Digit | '.' | '-' | '_' | ':' | CombiningChar | Extender
[5]     Name        ::=     (Letter | '_' | ':') (NameChar)*
其中定义了字母、数字等。请注意,字母必须在第一位

由于
ss
字符串可能包含无效字符,因此可以根据需要使用转义,然后在以后读取XML时使用恢复原始字符串

因此,您的代码看起来像:

    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;
        }
    }
public void write(字符串目录,XmlWriter)
{
尝试
{
writer.writeStarteElement(“文件夹”);
foreach(Directory.GetDirectories(Dir)中的字符串directoryPath)
{
字符串directoryName=Path.GetFileName(directoryPath);
writer.writeStarteElement(“文件夹”);
WriteAttributeString(“Name”,directoryName);
foreach(Directory.GetFiles(directoryPath)中的字符串文件名)
{
FileInfo fi=新的FileInfo(文件名);
writer.writeStart元素(“文件”);
WriteAttributeString(“名称”,文件名);
writer.WriteValue(fi.Length);
writer.writeedelement();
}
write(directoryPath,writer);//我将其移动到外部标记中。
writer.writeedelement();
}
writer.writeedelement();
}
捕获(未经授权的访问例外)
{
控制台写入线(例如消息);
返回;
}
捕获(IOEX异常)
{
控制台写入线(例如消息);
返回;
}
}
这将产生更可读的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>

1014
84992
187
326

与其尝试修复xml,不如使用Linq2Xml实现类似的功能

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



前面的空格正在使转义字符无效<代码>&为“&”,而
&是“&;”还有一个问题,所以你不需要为每个可能的无效字符编码。嘿,Paul,我在这个问题中只留了一个空格,因为没有它,它在这里正确地翻译了它,所以它给出了实际的&我甚至没有意识到他是在用文件夹名创建元素名。这是一个非常糟糕的主意,因为您不可能为它编写XSD。像
..
这样的东西会比
..
好得多,并且避免像文件夹名称以数字开头这样的问题。@PaulAbbott-同意。嘿,非常感谢各位,我接受了你们的建议,一切都很好。我可以问你如何使元素和元素字符串形成一棵树吗?@LukaZdravkovic-我的更新回答了你的问题吗?
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();