我是一名正在学习如何编码的学生。我被分配的任务是将数据从复杂的 XML 文件加载到列表中。我已经考虑了很长一段时间如何解决这个问题,这是我想出的最好的方法。然而,感觉不对。我缺少什么?真正的开发人员会如何处理这个问题?
private void loadFromFile(string filename)//load all data from file to list
{
try
{
XDocument doc = XDocument.Load(filename);
XElement sessioniGiornaliere = doc.Root.Element("SessioniGiornaliere");
if (sessioniGiornaliere != null)
{
foreach (XElement sessioneGiornaliera in sessioniGiornaliere.Elements("SessioneGiornaliera"))//sessione giornaliera is closed anytime there is there is a closingSession
{
List<CommercialDocument> documentList = new List<CommercialDocument>();//list of documents (containing type, es:"Vendita" ant totImport amount)
foreach (XElement type in sessioneGiornaliera.Elements("DocumentiEmessi").Elements("DocumentoCommerciale"))//scrolling trough every
{
List<Line> lineList = new List<Line>();
List<SubLine> subLines = new List<SubLine>(); //document before arriving at the Closure
string documentType = type.Elements().FirstOrDefault()?.Name.LocalName;
double amount = Convert.ToDouble(type.Element(documentType).Element("ImportoTotale")?.Value) / 100;
int numDocument = Convert.ToInt32(type.Element(documentType).Element("NumeroDocumento")?.Value);
foreach (XElement l in type.Elements("Vendita").Elements("Dettaglio").Elements("RigaGenerica"))//loading every doughter of riga generica
{
if(l.Element("Riga")!=null)//if the doughter is riga it loads everithing in the LineList
{
double equivalent = Convert.ToDouble(l.Element("Riga").Element("Elemento").Element("Importo")?.Value);
string description = l.Element("Riga").Element("Elemento").Element("Descrizione")?.Value;
int qt = Convert.ToInt32(l.Element("Riga").Element("Elemento").Element("Quantita")?.Value);
double unitPrice = Convert.ToDouble(l.Element("Riga").Element("Elemento").Element("PrezzoUnitario")?.Value);
double iva = 0;//set to 0 in case instead of IVA we have Natura (wich is the same as 0)
if(l.Element("Riga").Element("Elemento").Element("IVA")!=null)
iva = Convert.ToDouble(l.Element("Riga").Element("Elemento").Element("IVA").Element("AliquotaIVA")?.Value);
if (l.Element("Riga").Element("ModificatoreElemento")!=null)//if it has a modifier it aplies it before loading to the list
{
if (l.Element("Riga").Element("ModificatoreElemento").Element("Segno")?.Value == "-")
equivalent -= Convert.ToDouble(l.Element("Riga").Element("ModificatoreElemento").Element("Importo")?.Value);
else
equivalent += Convert.ToDouble(l.Element("Riga").Element("ModificatoreElemento").Element("Importo")?.Value);
}
Line line = new Line(equivalent/100,description, qt,unitPrice/100, iva / 100);//divifing by 100 because Convert.TODouble doesen't work somehow
lineList.Add(line);
}else if(l.Element("RigaSubtotale")!=null)//if it is Riga subTot it loads to a different list of the document because it has different preperties
{
double subTot = Convert.ToDouble(l.Element("RigaSubtotale").Element("SubTotale")?.Value);//cheks twice because it might have a subTot and not everything else
if (l.Element("RigaSubtotale").Element("ModificatoreSubTotale") != null)
{
double Import = Convert.ToDouble(l.Element("RigaSubtotale").Element("ModificatoreSubTotale").Element("Importi")?.Value);
string sign = Convert.ToString(l.Element("RigaSubtotale").Element("ModificatoreSubTotale").Element("Segno")?.Value);
string description = Convert.ToString(l.Element("RigaSubtotale").Element("ModificatoreSubTotale").Element("Descrizione")?.Value);
SubLine subLine = new SubLine(subTot/100, Import/100, sign, description);
subLines.Add(subLine);
}
}
}
CommercialDocument sellingDocument = new CommercialDocument(documentType, amount,lineList,subLines,numDocument);
documentList.Add(sellingDocument);//adding all to the documentList
}
foreach (XElement closingSession in sessioneGiornaliera.Elements("ChiusuraSessione"))//list of closing sessions
{
int number = Convert.ToInt32(closingSession.Element("Numero")?.Value);
double equivalent = Convert.ToDouble(closingSession.Element("Corrispettivo")?.Value);
double totCancel = Convert.ToDouble(closingSession.Element("TotaleAnnullo")?.Value);
double totRefound = Convert.ToDouble(closingSession.Element("TotaleReso")?.Value);
string date = closingSession.Element("DataOra")?.Value;
string TX_dir = sessioneGiornaliera.Element("TrasmissioneCorrispettivi").Element("DatiCorrispettivi").Element("NomeFile")?.Value;
TX_dir = filename[0] + ":" + TX_dir; //gets the directory to wich the more specific XML files are stored
ClosingSession a = new ClosingSession(date, equivalent / 100, totCancel / 100, totRefound / 100, documentList, TX_dir, number);
closingSessionList.Add(a);
}
Itemcounter++;
}
}
else
MessageBox.Show("file type incompatible");
}catch // all the exeptions are already managed and showed in the Valida function
{
}
}```
“真实”†编程中的一切都是上下文相关的。
如果数据的形状是固定的,并且数据大小合理,那么你通常会使用序列化库;对于 C# 来说,
XmlSerializer
可能是理想的选择,并且有一些工具可以从架构文件或示例 xml 文件自动生成起始代码。
如果数据的形状是动态的,则必须使用 DOM API 或 xslt 之类的东西,但这是一个更小众的场景。
如果数据量巨大(即太大而无法以 DOM 或反序列化对象模型的形式一次合理加载到内存中),则必须使用流 API,例如
XmlReader
;这是非常“困难的模式”,很少需要。
† 这里的引用是戏仿;我讨厌把关——我们不需要消除“真正的”程序员的歧义