[英]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 5
Hello everyone recently i have been making a c# app to read a xml file and it worked but now i was tasked with making it do that and read certain nodes from multiple xml files inside a certain folder and now i doesen´t work and shows that error in the title.大家好,最近我一直在制作 c# 应用程序来读取 xml 文件,它可以工作,但现在我的任务是让它做到这一点,并从多个 Z0F635D0E0F3874FFF8B581C132E6C7'Z 文件中读取某些节点,现在 iC7'A 文件在某些文件夹中不起作用标题错误。
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);
}
}
}
}
If you guys find the error help me out cause i need it.如果你们发现错误帮助我,因为我需要它。 Ps: the xml files follow the same roots ImportSession/Batches/Batch/Documents/Document/Pages/Page
Ps:xml 文件同根 ImportSession/Batches/Batch/Documents/Document/Pages/Page
Let's first clean up a little:让我们先清理一下:
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} {1}in 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
Next: System.Xml.XmlException
means there is something wrong with the xml input file. Next:
System.Xml.XmlException
表示 xml 输入文件有问题。
What can you do about that?你能做些什么呢?
Skip it, so the others may still be processed.跳过它,因此其他人可能仍会被处理。 Log the error, so you can later deep dive into the file, or request it be fixed and sent again.
记录错误,以便您以后可以深入研究该文件,或请求修复并再次发送。
If you have an XML Schema, you can validate the xml and easier find what exactly is wrong.如果您有 XML 架构,您可以验证xml 并更容易找到究竟是什么错误。 See XML schema (XSD) validation with XmlSchemaSet and/or XmlDocument.Validate Method .
请参阅使用 XmlSchemaSet 和/或XmlDocument.Validate 方法进行的 XML 架构 (XSD) 验证。
You can examine the input file manually and find the error.您可以手动检查输入文件并找到错误。 Mind that the message may sometimes be deceiving.
请注意,该信息有时可能具有欺骗性。 I'd start with checking if it is well-formed and valid xml (there are tools for that).
我首先检查它是否格式正确且有效 xml (有用于此的工具)。
I was able to resolve the problem with objects and their serialization.我能够解决对象及其序列化的问题。 You can find a way to do it with these two posts:
您可以通过以下两个帖子找到一种方法:
Objects: https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/objects对象: https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/objects
Objects serialization: https://docs.microsoft.com/en-us/dotnet/standard/serialization/how-to-serialize-an-object对象序列化: https://docs.microsoft.com/en-us/dotnet/standard/serialization/how-to-serialize-an-object
Giving some more context.提供更多上下文。
Start by making empty strings at the start of the method you're doing, it being a foreach loop or a if statement首先在您正在执行的方法的开头创建空字符串,它是 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();
}
}
After that start in my case my processfile
function之后在我的情况下开始我的进程文件
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, "");
There are two if statements inside this processfile that run checks on if there is a error inside the file and if the file as already been processed.此 processfile 中有两个 if 语句运行检查文件中是否存在错误以及文件是否已被处理。
I also added Insert into a stored procedure to make sure everything is complete in this edit I'm making.我还将 Insert 添加到存储过程中,以确保在我正在进行的编辑中一切都完成。
The objects I used are as follows我使用的对象如下
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);
}
And my stored procedure insert in case any of you are wondering how to do it我的存储过程插入以防你们中的任何人想知道如何去做
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();
}
}
Please comment if you don´t understand something ill help out.如果您不明白一些不好的帮助,请发表评论。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.