System.Xml.XmlException '根级别的数据无效,第 1 行,位置 1' 当我从 1 个 xml 文件更改为 5 时出现错误
Posted
技术标签:
【中文标题】System.Xml.XmlException \'根级别的数据无效,第 1 行,位置 1\' 当我从 1 个 xml 文件更改为 5 时出现错误【英文标题】:System.Xml.XmlException 'Data at the root level is invalid, line 1, position 1' error is showing up when i changed from 1 xml file to 5System.Xml.XmlException '根级别的数据无效,第 1 行,位置 1' 当我从 1 个 xml 文件更改为 5 时出现错误 【发布时间】:2021-04-24 19:22:24 【问题描述】:大家好,最近我一直在制作 ac# 应用程序来读取 xml 文件并且它可以工作,但现在我的任务是让它这样做并从某个文件夹内的多个 xml 文件中读取某些节点,现在我不工作了并在标题中显示该错误。
using System;
using System.Xml;
using System.IO;
namespace XmlReaderConsoleAPP
class Program
static void Main()
ProcessFile(@"C:\XMLFiles\SaintGobain_Pam_20210118.xml");
try
var path = @"C:\XMLFiles\SaintGobain_Pam_20210118.xml";
DirectoryInfo di = new DirectoryInfo(path);
foreach (var file in Directory.GetFiles(path))
Console.ReadKey();
catch(Exception ex)
Console.WriteLine("Erro: 0", ex.Message);
return;
static void ProcessFile(string Filename)
XmlDocument xml = new XmlDocument();
xml.LoadXml(Filename);
XmlNodeList xnLista = xml.SelectNodes(@"//ImportSession/Batches/batch/Documents/Document/Pages/Page");
Console.WriteLine($"Selected xnLista.Count nodes");
int i = 0;
foreach (XmlNode xn in xnLista)
Console.WriteLine($"++i xn.Name: xn.Attributes["ImportFileName"].Value");
XmlNodeList xnLista2 = xml.SelectNodes(@"//IndexFields/IndexField");
Console.WriteLine($"Selected xnLista2.Count nodes");
int j = 0;
foreach (XmlNode xn in xnLista2)
Console.WriteLine($"++j xn.Name: xn.Attributes["Value"].Value");
//string error = xn.Attributes["ErrorMessage"]?.Value;
//if (string.IsNullOrEmpty(error))
//
//
//elsex
//
//
Console.WriteLine(Filename);
如果你们发现错误,请帮助我,因为我需要它。 ps:xml文件同根ImportSession/Batches/Batch/Documents/Document/Pages/Page
【问题讨论】:
程序的结构似乎有点不对劲。您可能希望从 main 方法中提取 ProcessFile 方法(如果这不仅仅是复制和粘贴错误)。然后,您似乎两次处理同一个文件。一旦硬编码,然后再次进入循环(我建议使用 EnumerateFiles,顺便说一句)。但是,在循环内部,什么都没有发生?不太对,我猜。 @Fildor 更糟糕的是,OP 只处理文件一次,整个循环在这里毫无意义,因为 XML 内部存在一个尚未提供的问题。 @Tiago 请检查您的代码,逐行慢慢调试。还要检查您在第 1 行指定的文件的内容,我认为它不是有效的 XML @DavidG “但在循环内部,什么都没有发生?我猜不太对。” - 我意识到了这一点。 :) @Fildor 你说 OP 正在处理文件两次,我只是说这不是真的。 【参考方案1】:让我们先清理一下:
namespace XmlReaderConsoleAPP
class Program
static void Main()
var path = @"C:\XMLFiles";
var filter = @"*.xml"; // Add filter to only enumerate .xml files
foreach (var file in Directory.EnumerateFiles(path, filter))
// Move try/catch inside the loop to skip errornous files.
try
ProcessFile( file );
catch(Exception ex) // Usually, try to catch the specific as possible
Console.WriteLine("Error: 0 1in File 2",
ex.Message, Environment.NewLine, file);
Console.ReadKey();
// End of Main
static void ProcessFile(string Filename)
XmlDocument xml = new XmlDocument();
xml.LoadXml(Filename);
XmlNodeList xnLista = xml.SelectNodes(@"//ImportSession/Batches/batch/Documents/Document/Pages/Page");
Console.WriteLine($"Selected xnLista.Count nodes");
int i = 0;
foreach (XmlNode xn in xnLista)
Console.WriteLine($"++i xn.Name: xn.Attributes["ImportFileName"].Value");
XmlNodeList xnLista2 = xml.SelectNodes(@"//IndexFields/IndexField");
Console.WriteLine($"Selected xnLista2.Count nodes");
int j = 0;
foreach (XmlNode xn in xnLista2)
Console.WriteLine($"++j xn.Name: xn.Attributes["Value"].Value");
Console.WriteLine(Filename);
// class
// namespace
下一步:System.Xml.XmlException
表示 xml 输入文件有问题。
你能做些什么呢?
跳过它,这样其他的可能仍会被处理。记录错误,以便您以后深入研究文件,或请求修复并再次发送。
如果你有一个 XML Schema,你可以验证 xml 并且更容易找到究竟是什么错误。请参阅XML schema (XSD) validation with XmlSchemaSet 和/或XmlDocument.Validate Method。
您可以手动检查输入文件并找出错误。请注意,该信息有时可能具有欺骗性。我会先检查它是否格式正确且有效的 xml(有相应的工具)。
【讨论】:
你好 Fildor 我让它工作了,现在它显示了我需要的一切,但猜猜我现在需要做什么,就好像它只显示信息作为其中的特定信息,例如错误和批处理将其节点为 Processed = to 1 你也可以帮助我吗? ps:你帮了大忙。 当然,只需发布一个包含更新代码和新要求的新问题,我们就会知道您的问题出在哪里。【参考方案2】:我能够解决对象及其序列化的问题。 您可以通过以下两个帖子找到一种方法:
对象:https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/objects
对象序列化:https://docs.microsoft.com/en-us/dotnet/standard/serialization/how-to-serialize-an-object
提供更多上下文。
首先在您正在执行的方法的开头创建空字符串,它是 foreach 循环或 if 语句
class Program
static DataAccess da = new DataAccess();
public static void Main()
XmlSerializer serializer = new XmlSerializer(typeof(ImportSession));
foreach (string filename in Directory.EnumerateFiles(Properties.Settings.Default.PastaXML, "*.xml"))
string fName = "";
string BatchCName = "";
string batchName = "";
string description = "";
ProcessFile(filename, serializer, fName, BatchCName, batchName, description );
Console.ReadKey();
在我的情况下开始我的processfile
函数
private static void ProcessFile(string filename, XmlSerializer serializer, string fName, string batchName, string description, string BatchCName)
Console.WriteLine("A processar xml: " + filename);
bool temErro = false;
using (FileStream file = File.OpenRead(filename))
var session = (ImportSession)serializer.Deserialize(file);
foreach (Batch batch in session.Batches)
fName = Path.GetFileName(filename);
BatchCName = batch.BatchClassName;
batchName = batch.Name;
description = batch.Description;
foreach (Document doc in batch.Documents)
foreach (Page page in doc.Pages)
@ if (!string.IsNullOrEmpty(batch.Processed.ToString()))
if (page.HasError)
string Import = page.ImportFileName;
Console.WriteLine("Página com erro:" + Import + fName);
temErro = true;
da.SP_Insert(filename,fName,BatchCName,batchName,description,1,Import,0, "");
这个 processfile 中有两个 if 语句,用于检查文件中是否存在错误以及文件是否已被处理。
我还在存储过程中添加了 Insert 以确保在我正在进行的编辑中所有内容都已完成。
我使用的对象如下
public class ImportSession
public Batch[] Batches get; set;
public class Batch
[XmlAttribute]
public string Name get; set;
[XmlAttribute]
public string Description get; set;
[XmlAttribute]
public string BatchClassName get; set;
[XmlAttribute]
public bool Processed get; set;
public Document[] Documents get; set;
public class Document
[XmlAttribute]
public string FormTypeName get; set;
public IndexField[] IndexFields get; set;
public Page[] Pages get; set;
public class IndexField
[XmlAttribute]
public string Name get; set;
[XmlAttribute]
public string Value get; set;
public class Page
[XmlAttribute]
public string ImportFileName get; set;
[XmlAttribute]
public string ErrorCode get; set;
[XmlAttribute]
public string ErrorMessage get; set;
[XmlIgnore]
public bool HasError => !string.IsNullOrWhiteSpace(ErrorMessage);
我的存储过程插入以防你们中的任何人想知道如何去做
public void SP_Insert(string XMLPath, string XMLName, string BatchClassName, string BatchName,
string BatchDescription, int Error, string ErrorImagePath, int Done, string DonePath)
try
ManageConnectionState();
SqlCommand command = new SqlCommand("Sp_Insert", connection);
command.CommandType = CommandType.StoredProcedure;
command.Parameters.Add("@XMLPath",SqlDbType.NText).Value = XMLPath;
command.Parameters.Add("@XMLName",SqlDbType.NText).Value = XMLName;
command.Parameters.Add("@BatchClassName",SqlDbType.NText).Value= BatchClassName;
command.Parameters.Add("@BatchName",SqlDbType.NText ).Value = BatchName;
command.Parameters.Add("@BatchDescription", SqlDbType.NText ).Value = BatchDescription;
command.Parameters.Add("@Error",SqlDbType.Bit).Value = Error;
command.Parameters.Add("@ErrorImagePath", SqlDbType.NText).Value = ErrorImagePath;
command.Parameters.Add("@Done", SqlDbType.Bit ).Value=Done;
command.Parameters.Add("@DonePath", SqlDbType.NText).Value = DonePath;
command.ExecuteScalar();
catch (Exception ex)
Console.WriteLine("Erro: " + ex.Message);
finally
ManageConnectionState();
connection.Close();
如果有不明白的地方请评论帮忙。
【讨论】:
很好,你为此付出了很多努力。还有一些小的格式问题,我会看看那些,也许你也可以纠正。对于前两个 sn-ps:我不明白为什么需要这么多函数参数。据我所知,您只需要序列化程序和文件名。其余的参数,您可以在被调用的函数内创建为本地变量。 @Fildor ye 我有点做过,但是当我掌握了我在做什么并且在你和其他人的帮助下,我有点适应它并且它结束了工作,请告诉我我怎么能改进它 好的,所以ProcessFile
实际上只需要 private static void ProcessFile(string filename, XmlSerializer serializer)
。然后你可以将string fName = ""; ... string description = "";
移动到ProcessFile
方法中。只需将这些作为函数内的第一行即可。
@Fildor 我不想说你的错误,但不会改变我的 dataAccess 文件的制作方式,因为我从那里调用了 processfile 并且我拥有来自它们的所有变量
不。所有这些都设置在函数内部。据我从您的答案中的代码可以看出,在这里。以上是关于System.Xml.XmlException '根级别的数据无效,第 1 行,位置 1' 当我从 1 个 xml 文件更改为 5 时出现错误的主要内容,如果未能解决你的问题,请参考以下文章
System.Xml.XmlException:“':'字符,十六进制值 0x3A,不能包含在名称中。”
Web 服务调用导致 System.Xml.XmlException:'.',十六进制值 0x00
System.Xml.XmlException '根级别的数据无效,第 1 行,位置 1' 当我从 1 个 xml 文件更改为 5 时出现错误
System.Xml.XmlException: “=”是意外的标记。标记应为“;”