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